From 469bcf37d7a5ce74464fad9c30580e1b3c617e68 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 14:50:10 +0100 Subject: [PATCH 001/295] moved pynput threads to separate file --- pype/modules/idle_manager/idle_logic.py | 24 +++++++++++++++++++++++ pype/modules/idle_manager/idle_manager.py | 24 ----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 pype/modules/idle_manager/idle_logic.py diff --git a/pype/modules/idle_manager/idle_logic.py b/pype/modules/idle_manager/idle_logic.py new file mode 100644 index 0000000000..ab3f6790e6 --- /dev/null +++ b/pype/modules/idle_manager/idle_logic.py @@ -0,0 +1,24 @@ +from pynput import mouse, keyboard + + +class MouseThread(mouse.Listener): + """Listens user's mouse movement.""" + + def __init__(self, callback): + super(MouseThread, self).__init__(on_move=self.on_move) + self.callback = callback + + def on_move(self, posx, posy): + self.callback() + + +class KeyboardThread(keyboard.Listener): + """Listens user's keyboard input.""" + + def __init__(self, callback): + super(KeyboardThread, self).__init__(on_press=self.on_press) + + self.callback = callback + + def on_press(self, key): + self.callback() diff --git a/pype/modules/idle_manager/idle_manager.py b/pype/modules/idle_manager/idle_manager.py index fa6d70d229..3790d503ff 100644 --- a/pype/modules/idle_manager/idle_manager.py +++ b/pype/modules/idle_manager/idle_manager.py @@ -4,7 +4,6 @@ import threading from abc import ABCMeta, abstractmethod import six -from pynput import mouse, keyboard from pype.lib import PypeLogger from pype.modules import PypeModule, ITrayService @@ -162,26 +161,3 @@ class IdleManagerThread(threading.Thread): pass self.on_stop() - - -class MouseThread(mouse.Listener): - """Listens user's mouse movement.""" - - def __init__(self, callback): - super(MouseThread, self).__init__(on_move=self.on_move) - self.callback = callback - - def on_move(self, posx, posy): - self.callback() - - -class KeyboardThread(keyboard.Listener): - """Listens user's keyboard input.""" - - def __init__(self, callback): - super(KeyboardThread, self).__init__(on_press=self.on_press) - - self.callback = callback - - def on_press(self, key): - self.callback() From 6d09da37c07799c5bed7818bf8ee0668c5a535ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 14:50:24 +0100 Subject: [PATCH 002/295] import pynput threads only when needed --- pype/modules/idle_manager/idle_manager.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pype/modules/idle_manager/idle_manager.py b/pype/modules/idle_manager/idle_manager.py index 3790d503ff..81e03c96df 100644 --- a/pype/modules/idle_manager/idle_manager.py +++ b/pype/modules/idle_manager/idle_manager.py @@ -119,12 +119,18 @@ class IdleManagerThread(threading.Thread): self.log.info("IdleManagerThread has stopped") self.module.on_thread_stop() + def _create_threads(self): + from .idle_logic import MouseThread, KeyboardThread + + thread_mouse = MouseThread(self.reset_time) + thread_keyboard = KeyboardThread(self.reset_time) + return thread_mouse, thread_keyboard + def run(self): self.log.info("IdleManagerThread has started") self.is_running = True - thread_mouse = MouseThread(self.reset_time) + thread_mouse, thread_keyboard = self._create_threads() thread_mouse.start() - thread_keyboard = KeyboardThread(self.reset_time) thread_keyboard.start() try: while self.is_running: From 345e5971145a39b2b91cac1c5165361666ba3b03 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 14:50:33 +0100 Subject: [PATCH 003/295] minor change --- pype/modules/idle_manager/idle_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/modules/idle_manager/idle_manager.py b/pype/modules/idle_manager/idle_manager.py index 81e03c96df..25309e9443 100644 --- a/pype/modules/idle_manager/idle_manager.py +++ b/pype/modules/idle_manager/idle_manager.py @@ -98,7 +98,7 @@ class IdleManager(PypeModule, ITrayService): class IdleManagerThread(threading.Thread): def __init__(self, module, *args, **kwargs): super(IdleManagerThread, self).__init__(*args, **kwargs) - self.log = PypeLogger().get_logger(self.__class__.__name__) + self.log = PypeLogger.get_logger(self.__class__.__name__) self.module = module self.threads = [] self.is_running = False From d5a3e92f851e4ac19300dc1414b9922a18fe0707 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 14:51:30 +0100 Subject: [PATCH 004/295] renamed file `idle_manager` to `idle_module` --- pype/modules/idle_manager/__init__.py | 2 +- pype/modules/idle_manager/{idle_manager.py => idle_module.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename pype/modules/idle_manager/{idle_manager.py => idle_module.py} (100%) diff --git a/pype/modules/idle_manager/__init__.py b/pype/modules/idle_manager/__init__.py index 4bc33c87c1..651f360c50 100644 --- a/pype/modules/idle_manager/__init__.py +++ b/pype/modules/idle_manager/__init__.py @@ -1,4 +1,4 @@ -from .idle_manager import ( +from .idle_module import ( IdleManager, IIdleManager ) diff --git a/pype/modules/idle_manager/idle_manager.py b/pype/modules/idle_manager/idle_module.py similarity index 100% rename from pype/modules/idle_manager/idle_manager.py rename to pype/modules/idle_manager/idle_module.py From d233231a448d67b2a76b2dac7fe997936e4dd935 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 16:57:06 +0100 Subject: [PATCH 005/295] added SchemaError --- pype/settings/entities/exceptions.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pype/settings/entities/exceptions.py b/pype/settings/entities/exceptions.py index 951cd07243..ae1fd388a0 100644 --- a/pype/settings/entities/exceptions.py +++ b/pype/settings/entities/exceptions.py @@ -28,7 +28,13 @@ class InvalidValueType(Exception): super(InvalidValueType, self).__init__(msg) -class SchemaMissingFileInfo(Exception): + + +class SchemaError(Exception): + pass + + +class SchemaMissingFileInfo(SchemaError): def __init__(self, invalid): full_path_keys = [] for item in invalid: @@ -41,7 +47,7 @@ class SchemaMissingFileInfo(Exception): super(SchemaMissingFileInfo, self).__init__(msg) -class SchemeGroupHierarchyBug(Exception): +class SchemeGroupHierarchyBug(SchemaError): def __init__(self, entity_path): msg = ( "Items with attribute \"is_group\" can't have another item with" @@ -50,7 +56,7 @@ class SchemeGroupHierarchyBug(Exception): super(SchemeGroupHierarchyBug, self).__init__(msg) -class SchemaDuplicatedKeys(Exception): +class SchemaDuplicatedKeys(SchemaError): def __init__(self, entity_path, key): msg = ( "Schema item contain duplicated key \"{}\" in" @@ -59,7 +65,7 @@ class SchemaDuplicatedKeys(Exception): super(SchemaDuplicatedKeys, self).__init__(msg) -class SchemaDuplicatedEnvGroupKeys(Exception): +class SchemaDuplicatedEnvGroupKeys(SchemaError): def __init__(self, invalid): items = [] for key_path, keys in invalid.items(): @@ -74,7 +80,7 @@ class SchemaDuplicatedEnvGroupKeys(Exception): super(SchemaDuplicatedEnvGroupKeys, self).__init__(msg) -class SchemaTemplateMissingKeys(Exception): +class SchemaTemplateMissingKeys(SchemaError): def __init__(self, missing_keys, required_keys, template_name=None): self.missing_keys = missing_keys self.required_keys = required_keys From 512174256e08521a82295ec483dc9f67bb0ca6f6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 16:57:23 +0100 Subject: [PATCH 006/295] added exception for modifying required key --- pype/settings/entities/exceptions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/settings/entities/exceptions.py b/pype/settings/entities/exceptions.py index ae1fd388a0..7080a9b187 100644 --- a/pype/settings/entities/exceptions.py +++ b/pype/settings/entities/exceptions.py @@ -28,6 +28,10 @@ class InvalidValueType(Exception): super(InvalidValueType, self).__init__(msg) +class RequiredKeyModified(KeyError): + def __init__(self, entity_path, key): + msg = "{} - Tried to modify required key \"{}\"." + super(RequiredKeyModified, self).__init__(msg.format(entity_path, key)) class SchemaError(Exception): From 293d27abfff6f410a8c113f67af2574585bad652 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 16:57:57 +0100 Subject: [PATCH 007/295] raise an ex exception if required key is modified --- pype/settings/entities/dict_mutable_keys_entity.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index 2fd2b87311..f2058a4231 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -7,7 +7,8 @@ from .lib import ( from . import EndpointEntity from .exceptions import ( DefaultsNotDefined, - StudioDefaultsNotDefined + StudioDefaultsNotDefined, + RequiredKeyModified ) from pype.settings.constants import ( METADATA_KEYS, @@ -51,6 +52,8 @@ class DictMutableKeysEntity(EndpointEntity): return key in self.children_by_key def pop(self, key, *args, **kwargs): + if key in self.required_keys: + raise RequiredKeyModified(self.path, key) result = self.children_by_key.pop(key, *args, **kwargs) self.on_change() return result @@ -93,6 +96,9 @@ class DictMutableKeysEntity(EndpointEntity): child_obj.set(value) def change_key(self, old_key, new_key): + if old_key in self.required_keys: + raise RequiredKeyModified(self.path, old_key) + if new_key == old_key: return self.children_by_key[new_key] = self.children_by_key.pop(old_key) From fd1dbac6aadc2260b2c6e102edcc51d37eb097b9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 16:58:11 +0100 Subject: [PATCH 008/295] make sure that required key is always set --- pype/settings/entities/dict_mutable_keys_entity.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index f2058a4231..c8acb748cd 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -315,6 +315,10 @@ class DictMutableKeysEntity(EndpointEntity): for key in tuple(self.children_by_key.keys()): self.children_by_key.pop(key) + for required_key in self.required_keys: + if required_key not in new_value: + new_value[required_key] = NOT_SET + # Create new children children_label_by_id = {} metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {} From 3f13db2ef2dc5246e77b66fa04fa9d9dfc1bc19e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 17:14:41 +0100 Subject: [PATCH 009/295] view can show required keys --- .../settings/widgets/dict_mutable_widget.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/dict_mutable_widget.py b/pype/tools/settings/settings/widgets/dict_mutable_widget.py index b27e0e492b..53b2d1ddd2 100644 --- a/pype/tools/settings/settings/widgets/dict_mutable_widget.py +++ b/pype/tools/settings/settings/widgets/dict_mutable_widget.py @@ -827,10 +827,25 @@ class DictMutableKeysWidget(BaseWidget): while self.input_fields: self.remove_row(self.input_fields[0]) - for key, child_entity in self.entity.items(): + keys_order = list(self.entity.required_keys) + last_required = None + if keys_order: + last_required = keys_order[-1] + for key in self.entity.keys(): + if key in keys_order: + continue + keys_order.append(key) + + for key in keys_order: + child_entity = self.entity[key] input_field = self.add_widget_for_child(child_entity) input_field.origin_key = key - input_field.set_key(key) + if key in self.entity.required_keys: + input_field.set_as_required(key) + if key == last_required: + input_field.set_as_last_required() + else: + input_field.set_key(key) if self.entity.collapsible_key: label = self.entity.get_child_label(child_entity) input_field.origin_key_label = label From 3d025d7b788feec53c8c53d0df746cb97735d766 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 17:17:33 +0100 Subject: [PATCH 010/295] added required keys to example schema --- .../entities/schemas/system_schema/example_schema.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pype/settings/entities/schemas/system_schema/example_schema.json b/pype/settings/entities/schemas/system_schema/example_schema.json index 6e7a47d1bf..48a21cc0c6 100644 --- a/pype/settings/entities/schemas/system_schema/example_schema.json +++ b/pype/settings/entities/schemas/system_schema/example_schema.json @@ -141,6 +141,16 @@ "maximum": 100 } }, + { + "type": "dict-modifiable", + "key": "modifiable_dict_with_required_keys", + "label": "Modifiable dict with required keys", + "required_keys": [ + "key_1", + "key_2" + ], + "object_type": "text" + }, { "type": "list-strict", "key": "strict_list_labels_horizontal", From bf7e6fae43b77ae55af7d05139a64dde188622c1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 17 Mar 2021 17:24:28 +0100 Subject: [PATCH 011/295] fixed default values check --- pype/settings/entities/dict_mutable_keys_entity.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index c8acb748cd..8c9b5e03b1 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -451,7 +451,13 @@ class DictMutableKeysEntity(EndpointEntity): def update_default_value(self, value): value = self._check_update_value(value, "default") - self.has_default_value = value is not NOT_SET + has_default_value = value is not NOT_SET + if has_default_value: + for required_key in self.required_keys: + if required_key not in value: + has_default_value = False + break + self.has_default_value = has_default_value value, metadata = self._prepare_value(value) self._default_value = value self._default_metadata = metadata From 6337354ca95df02ff6817de06ede0aff35bda19d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:11:34 +0100 Subject: [PATCH 012/295] always register lists of callbacks as time may override them --- pype/modules/timers_manager/timers_manager.py | 12 ++++++------ pype/modules/timers_manager/widget_user_idle.py | 11 ++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pype/modules/timers_manager/timers_manager.py b/pype/modules/timers_manager/timers_manager.py index 68890640b3..b83f51f0ba 100644 --- a/pype/modules/timers_manager/timers_manager.py +++ b/pype/modules/timers_manager/timers_manager.py @@ -1,4 +1,5 @@ import os +import collections from abc import ABCMeta, abstractmethod import six from .. import PypeModule, ITrayService, IIdleManager, IWebServerRoutes @@ -159,26 +160,25 @@ class TimersManager(PypeModule, ITrayService, IIdleManager, IWebServerRoutes): def callbacks_by_idle_time(self): """Implementation of IIdleManager interface.""" # Time when message is shown - callbacks = { - self.time_show_message: lambda: self.time_callback(0) - } + callbacks = collections.defaultdict(list) + callbacks[self.time_show_message].append(lambda: self.time_callback(0)) # Times when idle is between show widget and stop timers show_to_stop_range = range( self.time_show_message - 1, self.time_stop_timer ) for num in show_to_stop_range: - callbacks[num] = lambda: self.time_callback(1) + callbacks[num].append(lambda: self.time_callback(1)) # Times when widget is already shown and user restart idle shown_and_moved_range = range( self.time_stop_timer - self.time_show_message ) for num in shown_and_moved_range: - callbacks[num] = lambda: self.time_callback(1) + callbacks[num].append(lambda: self.time_callback(1)) # Time when timers are stopped - callbacks[self.time_stop_timer] = lambda: self.time_callback(2) + callbacks[self.time_stop_timer].append(lambda: self.time_callback(2)) return callbacks diff --git a/pype/modules/timers_manager/widget_user_idle.py b/pype/modules/timers_manager/widget_user_idle.py index 5e47cdaddf..cbdb7fd30a 100644 --- a/pype/modules/timers_manager/widget_user_idle.py +++ b/pype/modules/timers_manager/widget_user_idle.py @@ -163,8 +163,9 @@ class SignalHandler(QtCore.QObject): signal_change_label = QtCore.Signal() signal_stop_timers = QtCore.Signal() - def __init__(self, cls): - super().__init__() - self.signal_show_message.connect(cls.show_message) - self.signal_change_label.connect(cls.change_label) - self.signal_stop_timers.connect(cls.stop_timers) + def __init__(self, module): + super(SignalHandler, self).__init__() + self.module = module + self.signal_show_message.connect(module.show_message) + self.signal_change_label.connect(module.change_label) + self.signal_stop_timers.connect(module.stop_timers) From 13d3b42617df5765fb9aeb56319f2553ebe2c900 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:39:01 +0100 Subject: [PATCH 013/295] store only application name to config --- pype/modules/ftrack/lib/avalon_sync.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index d639e814a5..e4631aad29 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -194,12 +194,8 @@ def get_project_apps(in_app_list): missing_app_msg = "Missing definition of application" application_manager = ApplicationManager() for app_name in in_app_list: - app = application_manager.applications.get(app_name) - if app: - apps.append({ - "name": app_name, - "label": app.full_label - }) + if application_manager.applications.get(app_name): + apps.append({"name": app_name}) else: warnings[missing_app_msg].append(app_name) return apps, warnings From 834aa9c4053d0e59a6fbb3d9de738bce3215e436 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:39:29 +0100 Subject: [PATCH 014/295] skip applications lookup if passed value is empty --- pype/modules/ftrack/lib/avalon_sync.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index e4631aad29..be1e150cb7 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -191,6 +191,9 @@ def get_project_apps(in_app_list): apps = [] warnings = collections.defaultdict(list) + if not in_app_list: + return apps, warnings + missing_app_msg = "Missing definition of application" application_manager = ApplicationManager() for app_name in in_app_list: From f4e11d69e3fb176aed2729a915a09b99ee6ac8a9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:39:38 +0100 Subject: [PATCH 015/295] pop applicaitons from data --- pype/modules/ftrack/lib/avalon_sync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index be1e150cb7..5ce6263198 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -1140,7 +1140,7 @@ class SyncEntitiesFactory: proj_schema = entity["project_schema"] task_types = proj_schema["_task_type_schema"]["types"] proj_apps, warnings = get_project_apps( - (data.get("applications") or []) + data.pop("applications", []) ) for msg, items in warnings.items(): if not msg or not items: From 166f623cd483bddd4baf6719e8b30a33f2947372 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:39:50 +0100 Subject: [PATCH 016/295] don't care about old parent name on rename --- pype/modules/ftrack/lib/avalon_sync.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 5ce6263198..bab69ab8e4 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -1427,8 +1427,13 @@ class SyncEntitiesFactory: old_parent_name = self.entities_dict[ self.ft_project_id]["name"] else: - old_parent_name = self.avalon_ents_by_id[ - ftrack_parent_mongo_id]["name"] + old_parent_name = "N/A" + if ftrack_parent_mongo_id in self.avalon_ents_by_id: + old_parent_name = ( + self.avalon_ents_by_id + [ftrack_parent_mongo_id] + ["name"] + ) self.updates[avalon_id]["data"] = { "visualParent": new_parent_id From b166b8133a809966ae387c42766ec5dfc8abdd7b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 18:40:06 +0100 Subject: [PATCH 017/295] task types are not overriden with new but only added new ones --- pype/modules/ftrack/lib/avalon_sync.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index bab69ab8e4..7a8800ffeb 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -2143,11 +2143,22 @@ class SyncEntitiesFactory: final_doc_data = self.entities_dict[self.ft_project_id]["final_entity"] final_doc_tasks = final_doc_data["config"].pop("tasks") current_doc_tasks = self.avalon_project.get("config", {}).get("tasks") - # Update project's tasks if tasks are empty or are not same - if not final_doc_tasks: + # Update project's task types + if not current_doc_tasks: update_tasks = True else: - update_tasks = final_doc_tasks != current_doc_tasks + # Check if task types are same + update_tasks = False + for task_type in final_doc_tasks: + if task_type not in current_doc_tasks: + update_tasks = True + break + + # Update new task types + # - but keep data about existing types and only add new one + if update_tasks: + for task_type, type_data in current_doc_tasks.items(): + final_doc_tasks[task_type] = type_data changes = self.compare_dict(final_doc_data, self.avalon_project) From 19ab249c6ddd1d6f1e88e6cee3bb345e30dd5850 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 19:03:28 +0100 Subject: [PATCH 018/295] applications are not stored to data in sync to avalon event --- .../event_sync_to_avalon.py | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 7c9c4d196f..a9e1f4282d 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1822,6 +1822,27 @@ class SyncToAvalonEvent(BaseEvent): ent_cust_attrs = [] for key, values in ent_info["changes"].items(): + if entType == "show" and key == "applications": + # Store apps to project't config + apps_str = ent_info["changes"]["applications"]["new"] + cust_attr_apps = [ + app_name.strip() + for app_name in apps_str.split(", ") if app_name + ] + + proj_apps, warnings = ( + avalon_sync.get_project_apps(cust_attr_apps) + ) + if "config" not in self.updates[mongo_id]: + self.updates[mongo_id]["config"] = {} + self.updates[mongo_id]["config"]["apps"] = proj_apps + + for msg, items in warnings.items(): + if not msg or not items: + continue + self.report_items["warning"][msg] = items + continue + if key in hier_attrs_keys: self.hier_cust_attrs_changes[key].append(ftrack_id) continue @@ -1839,25 +1860,6 @@ class SyncToAvalonEvent(BaseEvent): ) ) - if entType != "show" or key != "applications": - continue - - # Store apps to project't config - apps_str = ent_info["changes"]["applications"]["new"] - cust_attr_apps = [app for app in apps_str.split(", ") if app] - - proj_apps, warnings = ( - avalon_sync.get_project_apps(cust_attr_apps) - ) - if "config" not in self.updates[mongo_id]: - self.updates[mongo_id]["config"] = {} - self.updates[mongo_id]["config"]["apps"] = proj_apps - - for msg, items in warnings.items(): - if not msg or not items: - continue - self.report_items["warning"][msg] = items - def process_hier_cleanup(self): if ( not self.moved_in_avalon and From 63cc02e750165b03e9f191d42f5bc81ca7095f3a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 19:11:36 +0100 Subject: [PATCH 019/295] fixed collapsible_key dicitonary --- pype/tools/settings/settings/widgets/dict_mutable_widget.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/dict_mutable_widget.py b/pype/tools/settings/settings/widgets/dict_mutable_widget.py index 53b2d1ddd2..0cb051082e 100644 --- a/pype/tools/settings/settings/widgets/dict_mutable_widget.py +++ b/pype/tools/settings/settings/widgets/dict_mutable_widget.py @@ -358,7 +358,8 @@ class ModifiableDictItem(QtWidgets.QWidget): self.add_btn.setEnabled(False) def set_as_last_required(self): - self.add_btn.setEnabled(True) + if not self.collapsible_key: + self.add_btn.setEnabled(True) def _on_focus_lose(self): if ( From ebd6c08e76518184aadf70f454d0d2467a0b3be7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 10:59:40 +0100 Subject: [PATCH 020/295] mongo handler cache anatomy keys --- pype/settings/handlers.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 89f9645be7..004c2fe4c2 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -342,8 +342,25 @@ class MongoSettingsHandler(SettingsHandler): def __init__(self): # Get mongo connection from pype.lib import PypeMongoConnection + from avalon.api import AvalonMongoDB + from .entities import ProjectSettings + settings_collection = PypeMongoConnection.get_mongo_client() + # Prepare anatomy keys and attribute keys + # NOTE this is cached on first import + # - keys may change only on schema change which should not happen + # during production + project_settings_root = ProjectSettings( + reset=False, change_state=False + ) + anatomy_entity = project_settings_root["project_anatomy"] + anatomy_keys = set(anatomy_entity.keys()) + anatomy_keys.remove("attributes") + attribute_keys = set(anatomy_entity["attributes"].keys()) + + self.anatomy_keys = anatomy_keys + self.attribute_keys = attribute_keys # TODO prepare version of pype # - pype version should define how are settings saved and loaded @@ -357,6 +374,7 @@ class MongoSettingsHandler(SettingsHandler): self.collection_name = collection_name self.collection = settings_collection[database_name][collection_name] + self.avalon_db = AvalonMongoDB() self.system_settings_cache = CacheValues() self.project_settings_cache = collections.defaultdict(CacheValues) From 1d55c434b742e0012edf58fef477bad15768bf37 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 11:26:43 +0100 Subject: [PATCH 021/295] removed anatomy templates/roots entities --- pype/settings/entities/__init__.py | 10 +- pype/settings/entities/anatomy_entities.py | 94 ------------------- .../schemas/projects_schema/schema_main.json | 2 +- .../schemas/schema_anatomy_templates.json | 2 +- 4 files changed, 4 insertions(+), 104 deletions(-) diff --git a/pype/settings/entities/__init__.py b/pype/settings/entities/__init__.py index b48f763c73..20e00de4a5 100644 --- a/pype/settings/entities/__init__.py +++ b/pype/settings/entities/__init__.py @@ -105,11 +105,7 @@ from .list_entity import ListEntity from .dict_immutable_keys_entity import DictImmutableKeysEntity from .dict_mutable_keys_entity import DictMutableKeysEntity -from .anatomy_entities import ( - AnatomyEntity, - AnatomyRootsEntity, - AnatomyTemplatesEntity -) +from .anatomy_entities import AnatomyEntity __all__ = ( @@ -155,7 +151,5 @@ __all__ = ( "DictMutableKeysEntity", - "AnatomyEntity", - "AnatomyRootsEntity", - "AnatomyTemplatesEntity" + "AnatomyEntity" ) diff --git a/pype/settings/entities/anatomy_entities.py b/pype/settings/entities/anatomy_entities.py index 1b98bda4dd..4e16b8a840 100644 --- a/pype/settings/entities/anatomy_entities.py +++ b/pype/settings/entities/anatomy_entities.py @@ -1,102 +1,8 @@ from .dict_immutable_keys_entity import DictImmutableKeysEntity -from .dict_mutable_keys_entity import DictMutableKeysEntity class AnatomyEntity(DictImmutableKeysEntity): schema_types = ["anatomy"] - def _item_initalization(self): - self._roots_entity = None - self._templates_entity = None - - super(AnatomyEntity, self)._item_initalization() - - @property - def roots_entity(self): - if self._roots_entity is None: - _roots_entity = None - for child_entity in self.non_gui_children.values(): - if isinstance(child_entity, AnatomyRootsEntity): - _roots_entity = child_entity - break - - if _roots_entity is None: - raise KeyError( - "AnatomyEntity does not contain AnatomyRootsEntity" - ) - - self._roots_entity = _roots_entity - return self._roots_entity - - @property - def templates_entity(self): - if self._templates_entity is None: - _templates_entity = None - for child_entity in self.non_gui_children.values(): - if isinstance(child_entity, AnatomyTemplatesEntity): - _templates_entity = child_entity - break - - if _templates_entity is None: - raise KeyError( - "AnatomyEntity does not contain AnatomyRootsEntity" - ) - - self._templates_entity = _templates_entity - return self._templates_entity -class AnatomyRootsEntity(DictMutableKeysEntity): - schema_types = ["anatomy_roots"] - - def schema_validations(self): - if not isinstance(self.parent, AnatomyEntity): - raise TypeError("Parent of {} is not AnatomyEntity object".format( - self.__class__.__name__ - )) - super(AnatomyRootsEntity, self).schema_validations() - - @property - def has_studio_override(self): - output = super(AnatomyRootsEntity, self).has_studio_override - if not output: - output = self.parent.templates_entity._child_has_studio_override - return output - - @property - def has_project_override(self): - output = super(AnatomyRootsEntity, self).has_project_override - if not output: - output = self.parent.templates_entity._child_has_project_override - return output - - -class AnatomyTemplatesEntity(DictImmutableKeysEntity): - schema_types = ["anatomy_templates"] - - def schema_validations(self): - if not isinstance(self.parent, AnatomyEntity): - raise TypeError("Parent of {} is not AnatomyEntity object".format( - self.__class__.__name__ - )) - super(AnatomyTemplatesEntity, self).schema_validations() - - @property - def has_studio_override(self): - output = super(AnatomyTemplatesEntity, self).has_studio_override - if not output: - output = ( - self.parent.roots_entity._has_studio_override - or self.parent.roots_entity._child_has_studio_override - ) - return output - - @property - def has_project_override(self): - output = super(AnatomyTemplatesEntity, self).has_project_override - if not output: - output = ( - self.parent.roots_entity._has_project_override - or self.parent.roots_entity._child_has_project_override - ) - return output diff --git a/pype/settings/entities/schemas/projects_schema/schema_main.json b/pype/settings/entities/schemas/projects_schema/schema_main.json index 2ac6678d72..565500edd2 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_main.json +++ b/pype/settings/entities/schemas/projects_schema/schema_main.json @@ -10,7 +10,7 @@ { "key": "roots", "label": "Roots", - "type": "anatomy_roots", + "type": "dict-modifiable", "is_file": true, "is_group": true, "expandable": false, diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json index 8410ec48f4..918d3edba6 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json @@ -1,5 +1,5 @@ { - "type": "anatomy_templates", + "type": "dict", "key": "templates", "label": "Templates", "collapsible": true, From 95d8f7fb31c25edb4f2cc6679c7eccc74b20599e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 11:27:16 +0100 Subject: [PATCH 022/295] AnatomyEntity makes sure that all children all overriden on project overrides --- pype/settings/entities/anatomy_entities.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pype/settings/entities/anatomy_entities.py b/pype/settings/entities/anatomy_entities.py index 4e16b8a840..d048ffabba 100644 --- a/pype/settings/entities/anatomy_entities.py +++ b/pype/settings/entities/anatomy_entities.py @@ -1,8 +1,25 @@ from .dict_immutable_keys_entity import DictImmutableKeysEntity +from .lib import OverrideState class AnatomyEntity(DictImmutableKeysEntity): schema_types = ["anatomy"] + def _update_current_metadata(self): + if self._override_state is OverrideState.PROJECT: + return {} + return super(AnatomyEntity, self)._update_current_metadata() + def set_override_state(self, *args, **kwargs): + super(AnatomyEntity, self).set_override_state(*args, **kwargs) + if self._override_state is OverrideState.PROJECT: + for child_obj in self.non_gui_children.values(): + if not child_obj.has_project_override: + self.add_to_project_override() + break + def on_child_change(self, child_obj): + if self._override_state is OverrideState.PROJECT: + if not child_obj.has_project_override: + child_obj.add_to_project_override() + return super(AnatomyEntity, self).on_child_change(child_obj) From af1c18db1fee70f9bbc776926b6f47dd5ab8b87f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 12:03:53 +0100 Subject: [PATCH 023/295] added methods for conversion to valid value types --- pype/settings/entities/base_entity.py | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pype/settings/entities/base_entity.py b/pype/settings/entities/base_entity.py index 3a4bb23a90..6a0b11cc6c 100644 --- a/pype/settings/entities/base_entity.py +++ b/pype/settings/entities/base_entity.py @@ -324,6 +324,36 @@ class BaseItemEntity(BaseEntity): raise InvalidValueType(self.valid_value_types, type(value), self.path) + def _convert_to_valid_type(self, value): + """Private method of entity to convert value. + + NOTE: Method is not abstract as more entities won't have implemented + logic inside. + + Must return NOT_SET if can't convert the value. + """ + return NOT_SET + + def convert_to_valid_type(self, value): + """Check value type with possibility of conversion to valid. + + If entered value has right type than is returned as it is. otherwise + is used privete method of entity to try convert. + + Raises: + InvalidValueType: If value's type is not valid by entity's + definition and can't be converted by entity logic. + """ + # + if self.is_value_valid_type(value): + return value + + new_value = self._convert_to_valid_type(value) + if new_value is not NOT_SET and self.is_value_valid_type(new_value): + return new_value + + raise InvalidValueType(self.valid_value_types, type(value), self.path) + # TODO convert to private method def _check_update_value(self, value, value_source): """Validation of value on update methods. From 68d20b910e190d2d803b7de1feeb3332465351e8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 12:04:30 +0100 Subject: [PATCH 024/295] loaded values from default/studio/project are tried to convert --- pype/settings/entities/base_entity.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pype/settings/entities/base_entity.py b/pype/settings/entities/base_entity.py index 6a0b11cc6c..33abee227a 100644 --- a/pype/settings/entities/base_entity.py +++ b/pype/settings/entities/base_entity.py @@ -375,9 +375,13 @@ class BaseItemEntity(BaseEntity): if value is NOT_SET: return value - # Validate value type and return value itself if is valid. - if self.is_value_valid_type(value): - return value + try: + new_value = self.convert_to_valid_type(value) + except InvalidValueType: + new_value = NOT_SET + + if new_value is not NOT_SET: + return new_value # Warning log about invalid value type. self.log.warning( From eec4119177f4ab4a0028d7fb8b83988632bfcecf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 12:09:45 +0100 Subject: [PATCH 025/295] implemented some convertion methods --- pype/settings/entities/enum_entity.py | 6 ++++++ pype/settings/entities/input_entities.py | 15 ++++++++++++++- pype/settings/entities/list_entity.py | 5 +++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 4d6d268c70..437f37c469 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -46,6 +46,12 @@ class EnumEntity(InputEntity): super(EnumEntity, self).schema_validations() + def _convert_to_valid_type(self, value): + if self.multiselection: + if isinstance(value, (set, tuple)): + return list(value) + return NOT_SET + def set(self, value): if self.multiselection: if not isinstance(value, list): diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index c26cb249a6..1f57578094 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -330,7 +330,7 @@ class NumberEntity(InputEntity): self.decimal = self.schema_data.get("decimal", 0) if self.decimal: - valid_value_types = (int, float) + valid_value_types = (float, ) else: valid_value_types = (int, ) self.valid_value_types = valid_value_types @@ -340,6 +340,19 @@ class NumberEntity(InputEntity): # TODO check number for floats, integers and point self._validate_value_type(value) super(NumberEntity, self).set(value) + def _convert_to_valid_type(self, value): + if self.decimal: + if isinstance(value, int): + return float(value) + else: + if isinstance(value, float): + new_value = int(value) + if new_value != value: + self.log.info("Converted float {} to int {}".format( + value, new_value + )) + return new_value + return NOT_SET class BoolEntity(InputEntity): diff --git a/pype/settings/entities/list_entity.py b/pype/settings/entities/list_entity.py index 752347489a..ab112236f8 100644 --- a/pype/settings/entities/list_entity.py +++ b/pype/settings/entities/list_entity.py @@ -126,6 +126,11 @@ class ListEntity(EndpointEntity): ) self.on_change() + def _convert_to_valid_type(self, value): + if isinstance(value, (set, tuple)): + return list(value) + return NOT_SET + def _item_initalization(self): self.valid_value_types = (list, ) self.children = [] From 561ad4b8c69c3ed7a4cc16810490e41335626c98 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 12:11:49 +0100 Subject: [PATCH 026/295] setter methods use conversion method --- .../entities/dict_immutable_keys_entity.py | 4 ++-- .../entities/dict_mutable_keys_entity.py | 4 ++-- pype/settings/entities/enum_entity.py | 14 ++++---------- pype/settings/entities/input_entities.py | 17 ++++++----------- pype/settings/entities/item_entities.py | 4 ++-- pype/settings/entities/list_entity.py | 4 ++-- pype/settings/entities/root_entities.py | 4 ++-- 7 files changed, 20 insertions(+), 31 deletions(-) diff --git a/pype/settings/entities/dict_immutable_keys_entity.py b/pype/settings/entities/dict_immutable_keys_entity.py index 208f976314..d797320583 100644 --- a/pype/settings/entities/dict_immutable_keys_entity.py +++ b/pype/settings/entities/dict_immutable_keys_entity.py @@ -70,8 +70,8 @@ class DictImmutableKeysEntity(ItemEntity): def set(self, value): """Set value.""" - self._validate_value_type(value) - for _key, _value in value.items(): + new_value = self.convert_to_valid_type(value) + for _key, _value in new_value.items(): self.non_gui_children[_key].set(_value) def schema_validations(self): diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index 2fd2b87311..f930d3738b 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -72,11 +72,11 @@ class DictMutableKeysEntity(EndpointEntity): self.pop(key) def set(self, value): - self._validate_value_type(value) + new_value = self.convert_to_valid_type(value) prev_keys = set(self.keys()) - for _key, _value in value.items(): + for _key, _value in new_value.items(): self.set_key_value(_key, _value) if _key in prev_keys: prev_keys.remove(_key) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 437f37c469..f2831c78dc 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -53,17 +53,11 @@ class EnumEntity(InputEntity): return NOT_SET def set(self, value): + new_value = self.convert_to_valid_type(value) if self.multiselection: - if not isinstance(value, list): - if isinstance(value, (set, tuple)): - value = list(value) - else: - value = [value] - check_values = value + check_values = new_value else: - check_values = [value] - - self._validate_value_type(value) + check_values = [new_value] for item in check_values: if item not in self.valid_keys: @@ -72,7 +66,7 @@ class EnumEntity(InputEntity): item, self.valid_keys ) ) - self._current_value = value + self._current_value = new_value self._on_value_change() diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index 1f57578094..1e781ae951 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -121,8 +121,7 @@ class InputEntity(EndpointEntity): def set(self, value): """Change value.""" - self._validate_value_type(value) - self._current_value = value + self._current_value = self.convert_to_valid_type(value) self._on_value_change() def _on_value_change(self): @@ -336,10 +335,6 @@ class NumberEntity(InputEntity): self.valid_value_types = valid_value_types self.value_on_not_set = 0 - def set(self, value): - # TODO check number for floats, integers and point - self._validate_value_type(value) - super(NumberEntity, self).set(value) def _convert_to_valid_type(self, value): if self.decimal: if isinstance(value, int): @@ -401,13 +396,13 @@ class RawJsonEntity(InputEntity): self.project_override_metadata = {} def set(self, value): - self._validate_value_type(value) + new_value = self.convert_to_valid_type(value) - if isinstance(value, dict): + if isinstance(new_value, dict): for key in METADATA_KEYS: - if key in value: - value.pop(key) - self._current_value = value + if key in new_value: + new_value.pop(key) + self._current_value = new_value self._on_value_change() @property diff --git a/pype/settings/entities/item_entities.py b/pype/settings/entities/item_entities.py index 11e43e4fa6..da36bbbc2a 100644 --- a/pype/settings/entities/item_entities.py +++ b/pype/settings/entities/item_entities.py @@ -239,8 +239,8 @@ class ListStrictEntity(ItemEntity): return output def set(self, value): - self._validate_value_type(value) - for idx, item in enumerate(value): + new_value = self.convert_to_valid_type(value) + for idx, item in enumerate(new_value): self.children[idx].set(item) def settings_value(self): diff --git a/pype/settings/entities/list_entity.py b/pype/settings/entities/list_entity.py index ab112236f8..814086fe0f 100644 --- a/pype/settings/entities/list_entity.py +++ b/pype/settings/entities/list_entity.py @@ -180,9 +180,9 @@ class ListEntity(EndpointEntity): return "/".join([self.path, str(result_idx)]) def set(self, value): - self._validate_value_type(value) + new_value = self.convert_to_valid_type(value) self.clear() - for item in value: + for item in new_value: self.append(item) def on_child_change(self, _child_entity): diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index b4dc667826..e9000015b2 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -82,8 +82,8 @@ class RootEntity(BaseItemEntity): def set(self, value): """Set value.""" - self._validate_value_type(value) - for _key, _value in value.items(): + new_value = self.convert_to_valid_type(value) + for _key, _value in new_value.items(): self.non_gui_children[_key].set(_value) def keys(self): From d0fec1108998dee6f06be080fc03cd6a2d0eccb2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 12:27:07 +0100 Subject: [PATCH 027/295] added method to convert project document to anatomy data --- pype/settings/handlers.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 004c2fe4c2..fb724fffcf 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -505,6 +505,38 @@ class MongoSettingsHandler(SettingsHandler): return {} return self._get_project_settings_overrides(project_name) + def project_doc_to_anatomy_data(self, project_doc): + """Convert project document to anatomy data. + + Probably should fill missing keys and values. + """ + attributes = {} + project_doc_data = project_doc.get("data") or {} + for key in self.attribute_keys: + value = project_doc_data.get(key) + if value is not None: + attributes[key] = value + + project_doc_config = project_doc.get("config") or {} + app_names = set() + if "apps" in project_doc_config: + for app_item in project_doc_config.pop("apps"): + if not app_item: + continue + app_name = app_item.get("name") + if app_name: + app_names.add(app_name) + + attributes["applications"] = list(app_names) + + output = {"attributes": attributes} + for key in self.anatomy_keys: + value = project_doc_config.get(key) + if value is not None: + output[key] = value + + return output + def _get_project_anatomy_overrides(self, project_name): if self.project_anatomy_cache[project_name].is_outdated: document_filter = { From 150adabff002dba2db33b4b37fd93095adce823f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 13:01:52 +0100 Subject: [PATCH 028/295] implemented way how to load and save anatomy data to project document --- pype/settings/handlers.py | 109 ++++++++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 11 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index fb724fffcf..48e6ca395c 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -438,8 +438,90 @@ class MongoSettingsHandler(SettingsHandler): data_cache = self.project_anatomy_cache[project_name] data_cache.update_data(anatomy_data) - self._save_project_data( - project_name, PROJECT_ANATOMY_KEY, data_cache + if project_name is not None: + self._save_project_anatomy_data(project_name, data_cache) + + else: + self._save_project_data( + project_name, PROJECT_ANATOMY_KEY, data_cache + ) + + @classmethod + def prepare_mongo_update_dict(cls, in_data): + data = {} + for key, value in in_data.items(): + if not isinstance(value, dict): + data[key] = value + continue + + new_value = cls.prepare_mongo_update_dict(value) + for _key, _value in new_value.items(): + new_key = ".".join((key, _key)) + data[new_key] = _value + + return data + + def _save_project_anatomy_data(self, project_name, data_cache): + # Create copy of data as they will be modified during save + new_data = data_cache.data_copy() + + # Prepare avalon project document + collection = self.avalon_db.database[project_name] + project_doc = collection.find_one({ + "type": "project" + }) + if not project_doc: + raise ValueError(( + "Project document of project \"{}\" does not exists." + " Create project first." + ).format(project_name)) + + # Update dictionary of changes that will be changed in mongo + update_dict = {} + + # Project's data + update_dict_data = {} + project_doc_data = project_doc.get("data") or {} + attributes = new_data.pop("attributes") + _applications = attributes.pop("applications", None) or [] + for key, value in attributes.items(): + if ( + key in project_doc_data + and project_doc_data[key] == value + ): + continue + update_dict_data[key] = value + + if update_dict_data: + update_dict["data"] = update_dict_data + + update_dict_config = {} + + applications = [] + for application in _applications: + if not application: + continue + if isinstance(application, six.string_types): + applications.append({application: application}) + + new_data["apps"] = applications + + for key, value in new_data.items(): + project_doc_value = project_doc.get(key) + if key in project_doc and project_doc_value == value: + continue + update_dict_config[key] = value + + if update_dict_config: + update_dict["config"] = update_dict_config + + if not update_dict: + return + + _update_dict = self.prepare_mongo_update_dict(update_dict) + collection.update_one( + {"type": "project"}, + {"$set": _update_dict} ) def _save_project_data(self, project_name, doc_type, data_cache): @@ -539,17 +621,22 @@ class MongoSettingsHandler(SettingsHandler): def _get_project_anatomy_overrides(self, project_name): if self.project_anatomy_cache[project_name].is_outdated: - document_filter = { - "type": PROJECT_ANATOMY_KEY, - } if project_name is None: - document_filter["is_default"] = True + document_filter = { + "type": PROJECT_ANATOMY_KEY, + "is_default": True + } + document = self.collection.find_one(document_filter) + self.project_anatomy_cache[project_name].update_from_document( + document + ) else: - document_filter["project_name"] = project_name - document = self.collection.find_one(document_filter) - self.project_anatomy_cache[project_name].update_from_document( - document - ) + collection = self.avalon_db.database[project_name] + project_doc = collection.find_one({"type": "project"}) + self.project_anatomy_cache[project_name].update_data( + self.project_doc_to_anatomy_data(project_doc) + ) + return self.project_anatomy_cache[project_name].data_copy() def get_studio_project_anatomy_overrides(self): From 544869cd314b26f6b74c071e5ef871097f405dc1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 13:27:30 +0100 Subject: [PATCH 029/295] it is possible to define keys to query for custom attributes --- pype/modules/ftrack/lib/avalon_sync.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 7a8800ffeb..f7feec7475 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -83,15 +83,23 @@ def check_regex(name, entity_type, in_schema=None, schema_patterns=None): return False -def get_pype_attr(session, split_hierarchical=True): +def get_pype_attr(session, split_hierarchical=True, query_keys=None): custom_attributes = [] hier_custom_attributes = [] + if not query_keys: + query_keys = [ + "id", + "entity_type", + "object_type_id", + "is_hierarchical", + "default" + ] # TODO remove deprecated "avalon" group from query cust_attrs_query = ( - "select id, entity_type, object_type_id, is_hierarchical, default" + "select {}" " from CustomAttributeConfiguration" - " where group.name in (\"avalon\", \"pype\")" - ) + " where group.name in (\"avalon\", \"{}\")" + ).format(join_query_keys(query_keys), CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: if split_hierarchical and cust_attr["is_hierarchical"]: From 21ba1896a218aa8cb7d6c4ae60a9a81f6eebf77c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 13:27:39 +0100 Subject: [PATCH 030/295] implemented join query keys --- pype/modules/ftrack/lib/avalon_sync.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index f7feec7475..f0306c2073 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -83,6 +83,10 @@ def check_regex(name, entity_type, in_schema=None, schema_patterns=None): return False +def join_query_keys(keys): + return ",".join(["\"{}\"".format(key) for key in keys]) + + def get_pype_attr(session, split_hierarchical=True, query_keys=None): custom_attributes = [] hier_custom_attributes = [] From 4408137bdef5ab7ebd218a8921f0e47238dfdeb4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:53:42 +0100 Subject: [PATCH 031/295] fix key query --- pype/modules/ftrack/lib/avalon_sync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index f0306c2073..addc8a4a9c 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -103,7 +103,7 @@ def get_pype_attr(session, split_hierarchical=True, query_keys=None): "select {}" " from CustomAttributeConfiguration" " where group.name in (\"avalon\", \"{}\")" - ).format(join_query_keys(query_keys), CUST_ATTR_GROUP) + ).format(", ".join(query_keys), CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: if split_hierarchical and cust_attr["is_hierarchical"]: From 85a03bd2d7f41dddbeeb6e367d6760a65dd455f1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:54:22 +0100 Subject: [PATCH 032/295] implemented method that can convert changes string to value --- .../event_sync_to_avalon.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index a9e1f4282d..443e428c01 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1,6 +1,7 @@ import os import collections import copy +import json import queue import time import datetime @@ -10,6 +11,7 @@ import traceback from bson.objectid import ObjectId from pymongo import UpdateOne +import arrow import ftrack_api from avalon import schema @@ -1860,6 +1862,41 @@ class SyncToAvalonEvent(BaseEvent): ) ) + def convert_value_by_cust_attr_conf(self, value, cust_attr_conf): + type_id = cust_attr_conf["type_id"] + cust_attr_type_name = self.cust_attr_types_by_id[type_id]["name"] + ignored = ( + "expression", "notificationtype", "dynamic enumerator" + ) + if cust_attr_type_name in ignored: + return None + + if cust_attr_type_name == "text": + return value + + if cust_attr_type_name == "boolean": + if value == "1": + return True + if value == "0": + return False + return bool(value) + + if cust_attr_type_name == "date": + return arrow.get(value) + + cust_attr_config = json.loads(cust_attr_conf["config"]) + + if cust_attr_type_name == "number": + if cust_attr_config["isdecimal"]: + return float(value) + return int(value) + + if cust_attr_type_name == "enumerator": + if not cust_attr_config["multiSelect"]: + return value + return value.split(", ") + return value + def process_hier_cleanup(self): if ( not self.moved_in_avalon and From d40165ef946993d836837dd5e4bea81ac1a0650a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:55:02 +0100 Subject: [PATCH 033/295] removed duplicated property avalon_custom_attributes --- .../event_handlers_server/event_sync_to_avalon.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 443e428c01..497edf1ae4 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -229,15 +229,6 @@ class SyncToAvalonEvent(BaseEvent): return self._changeability_by_mongo_id - @property - def avalon_custom_attributes(self): - """Return info about changeability of entity and it's parents.""" - if self._avalon_custom_attributes is None: - self._avalon_custom_attributes = avalon_sync.get_pype_attr( - self.process_session - ) - return self._avalon_custom_attributes - def remove_cached_by_key(self, key, values): if self._avalon_ents is None: return @@ -393,7 +384,6 @@ class SyncToAvalonEvent(BaseEvent): self._avalon_archived_by_id = None self._avalon_archived_by_name = None - self._avalon_custom_attributes = None self._ent_types_by_name = None self.ftrack_ents_by_id = {} @@ -1238,7 +1228,7 @@ class SyncToAvalonEvent(BaseEvent): def get_cust_attr_values(self, entity, keys=None): output = {} - custom_attrs, hier_attrs = self.avalon_custom_attributes + custom_attrs, hier_attrs = self.avalon_cust_attrs not_processed_keys = True if keys: not_processed_keys = [k for k in keys] From 40865b992af3352358574ff92f5dc56b814b9193 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:55:14 +0100 Subject: [PATCH 034/295] define query keys of custom attributes --- .../event_handlers_server/event_sync_to_avalon.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 497edf1ae4..8f53d61781 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -33,6 +33,15 @@ class SyncToAvalonEvent(BaseEvent): ignore_ent_types = ["Milestone"] ignore_keys = ["statusid", "thumbid"] + cust_attr_query_keys = [ + "id", + "key", + "entity_type", + "object_type_id", + "is_hierarchical", + "config", + "default" + ] project_query = ( "select full_name, name, custom_attributes" ", project_schema._task_type_schema.types.name" @@ -117,7 +126,7 @@ class SyncToAvalonEvent(BaseEvent): def avalon_cust_attrs(self): if self._avalon_cust_attrs is None: self._avalon_cust_attrs = avalon_sync.get_pype_attr( - self.process_session + self.process_session, query_keys=self.cust_attr_query_keys ) return self._avalon_cust_attrs From 1c7010b0cbf87d1a45cdbdce9c3de3389e297ed9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:55:43 +0100 Subject: [PATCH 035/295] implemented property cust_attr_types_by_id --- .../event_handlers_server/event_sync_to_avalon.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 8f53d61781..2b6f2e33df 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -130,6 +130,18 @@ class SyncToAvalonEvent(BaseEvent): ) return self._avalon_cust_attrs + @property + def cust_attr_types_by_id(self): + if self._cust_attr_types_by_id is None: + cust_attr_types = self.process_session.query( + "select id, name from CustomAttributeType" + ).all() + self._cust_attr_types_by_id = { + cust_attr_type["id"]: cust_attr_type + for cust_attr_type in cust_attr_types + } + return self._cust_attr_types_by_id + @property def avalon_entities(self): if self._avalon_ents is None: @@ -382,6 +394,7 @@ class SyncToAvalonEvent(BaseEvent): self._cur_project = None self._avalon_cust_attrs = None + self._cust_attr_types_by_id = None self._avalon_ents = None self._avalon_ents_by_id = None From 0231c73cf773d2903cec1f273af7436e76858429 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:55:50 +0100 Subject: [PATCH 036/295] fixed ordered dict --- .../ftrack/event_handlers_server/event_sync_to_avalon.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 2b6f2e33df..cf5b9d4e26 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1562,10 +1562,9 @@ class SyncToAvalonEvent(BaseEvent): ).format(entity_type, ent_info["entityType"])) continue - _entity_key = collections.OrderedDict({ - "configuration_id": mongo_id_configuration_id, - "entity_id": ftrack_id - }) + _entity_key = collections.OrderedDict() + _entity_key["configuration_id"] = mongo_id_configuration_id + _entity_key["entity_id"] = ftrack_id self.process_session.recorded_operations.push( ftrack_api.operation.UpdateEntityOperation( From a6b8300c32a369eb7278660fb3d31d9b3e00a2db Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:56:10 +0100 Subject: [PATCH 037/295] event value is converted to real value --- .../event_sync_to_avalon.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index cf5b9d4e26..fec2d672cf 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1803,6 +1803,10 @@ class SyncToAvalonEvent(BaseEvent): return cust_attrs, hier_attrs = self.avalon_cust_attrs + hier_attrs_by_key = { + attr["key"]: attr + for attr in hier_attrs + } cust_attrs_by_obj_id = collections.defaultdict(dict) for cust_attr in cust_attrs: key = cust_attr["key"] @@ -1818,8 +1822,6 @@ class SyncToAvalonEvent(BaseEvent): obj_id = cust_attr["object_type_id"] cust_attrs_by_obj_id[obj_id][key] = cust_attr - hier_attrs_keys = [attr["key"] for attr in hier_attrs] - for ftrack_id, ent_info in ent_infos.items(): mongo_id = ftrack_mongo_mapping[ftrack_id] entType = ent_info["entityType"] @@ -1832,19 +1834,25 @@ class SyncToAvalonEvent(BaseEvent): # Ftrack's entity_type does not have defined custom attributes if ent_cust_attrs is None: - ent_cust_attrs = [] + ent_cust_attrs = {} for key, values in ent_info["changes"].items(): + if key in hier_attrs_by_key: + self.hier_cust_attrs_changes[key].append(ftrack_id) + continue + + if key not in ent_cust_attrs: + continue + + value = values["new"] + new_value = self.convert_value_by_cust_attr_conf( + value, ent_cust_attrs[key] + ) + if entType == "show" and key == "applications": # Store apps to project't config - apps_str = ent_info["changes"]["applications"]["new"] - cust_attr_apps = [ - app_name.strip() - for app_name in apps_str.split(", ") if app_name - ] - proj_apps, warnings = ( - avalon_sync.get_project_apps(cust_attr_apps) + avalon_sync.get_project_apps(new_value) ) if "config" not in self.updates[mongo_id]: self.updates[mongo_id]["config"] = {} @@ -1856,20 +1864,12 @@ class SyncToAvalonEvent(BaseEvent): self.report_items["warning"][msg] = items continue - if key in hier_attrs_keys: - self.hier_cust_attrs_changes[key].append(ftrack_id) - continue - - if key not in ent_cust_attrs: - continue - if "data" not in self.updates[mongo_id]: self.updates[mongo_id]["data"] = {} - value = values["new"] - self.updates[mongo_id]["data"][key] = value + self.updates[mongo_id]["data"][key] = new_value self.log.debug( "Setting data value of \"{}\" to \"{}\" <{}>".format( - key, value, ent_path + key, new_value, ent_path ) ) From 2e569e70af673458bd33bc75f9e7986117238b49 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:56:21 +0100 Subject: [PATCH 038/295] use join function --- .../ftrack/event_handlers_server/event_sync_to_avalon.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index fec2d672cf..c1c0ac0032 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -2137,16 +2137,12 @@ class SyncToAvalonEvent(BaseEvent): parent_queue.put(parent_ent) # Prepare values to query - entity_ids_joined = ", ".join([ - "\"{}\"".format(id) for id in cust_attrs_ftrack_ids - ]) configuration_ids = set() for key in hier_cust_attrs_keys: configuration_ids.add(hier_attr_id_by_key[key]) - attributes_joined = ", ".join([ - "\"{}\"".format(conf_id) for conf_id in configuration_ids - ]) + entity_ids_joined = self.join_query_keys(cust_attrs_ftrack_ids) + attributes_joined = self.join_query_keys(configuration_ids) queries = [{ "action": "query", From e98fe26aa8fe0223c309d4361ea56d884527fc30 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 14:56:27 +0100 Subject: [PATCH 039/295] formatting changes --- .../ftrack/event_handlers_server/event_sync_to_avalon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index c1c0ac0032..d71a94aabf 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -2018,7 +2018,7 @@ class SyncToAvalonEvent(BaseEvent): self.update_entities() return - cust_attrs, hier_attrs = self.avalon_cust_attrs + _, hier_attrs = self.avalon_cust_attrs # Hierarchical custom attributes preparation *** hier_attr_key_by_id = { From 4c28395143b6df3fed4e3379cd47109825010c8c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:00:41 +0100 Subject: [PATCH 040/295] renamed idle_logic to idle_threads --- pype/modules/idle_manager/{idle_logic.py => idle_threads.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pype/modules/idle_manager/{idle_logic.py => idle_threads.py} (100%) diff --git a/pype/modules/idle_manager/idle_logic.py b/pype/modules/idle_manager/idle_threads.py similarity index 100% rename from pype/modules/idle_manager/idle_logic.py rename to pype/modules/idle_manager/idle_threads.py From 6908ae0e4e14720d736f8ce51e8eb20b33a239eb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:01:00 +0100 Subject: [PATCH 041/295] moved idle thread to threads file --- pype/modules/idle_manager/idle_module.py | 84 ++--------------------- pype/modules/idle_manager/idle_threads.py | 73 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 78 deletions(-) diff --git a/pype/modules/idle_manager/idle_module.py b/pype/modules/idle_manager/idle_module.py index 25309e9443..979e1b92ea 100644 --- a/pype/modules/idle_manager/idle_module.py +++ b/pype/modules/idle_manager/idle_module.py @@ -1,11 +1,8 @@ -import time import collections -import threading from abc import ABCMeta, abstractmethod import six -from pype.lib import PypeLogger from pype.modules import PypeModule, ITrayService @@ -79,11 +76,16 @@ class IdleManager(PypeModule, ITrayService): if self.idle_thread and self.idle_thread.is_running: return self.idle_thread.idle_time + def _create_thread(self): + from .idle_threads import IdleManagerThread + + return IdleManagerThread(self) + def start_thread(self): if self.idle_thread: self.idle_thread.stop() self.idle_thread.join() - self.idle_thread = IdleManagerThread(self) + self.idle_thread = self._create_thread() self.idle_thread.start() def stop_thread(self): @@ -93,77 +95,3 @@ class IdleManager(PypeModule, ITrayService): def on_thread_stop(self): self.set_service_failed_icon() - - -class IdleManagerThread(threading.Thread): - def __init__(self, module, *args, **kwargs): - super(IdleManagerThread, self).__init__(*args, **kwargs) - self.log = PypeLogger.get_logger(self.__class__.__name__) - self.module = module - self.threads = [] - self.is_running = False - self.idle_time = 0 - - def stop(self): - self.is_running = False - - def reset_time(self): - self.idle_time = 0 - - @property - def time_callbacks(self): - return self.module.time_callbacks - - def on_stop(self): - self.is_running = False - self.log.info("IdleManagerThread has stopped") - self.module.on_thread_stop() - - def _create_threads(self): - from .idle_logic import MouseThread, KeyboardThread - - thread_mouse = MouseThread(self.reset_time) - thread_keyboard = KeyboardThread(self.reset_time) - return thread_mouse, thread_keyboard - - def run(self): - self.log.info("IdleManagerThread has started") - self.is_running = True - thread_mouse, thread_keyboard = self._create_threads() - thread_mouse.start() - thread_keyboard.start() - try: - while self.is_running: - if self.idle_time in self.time_callbacks: - for callback in self.time_callbacks[self.idle_time]: - thread = threading.Thread(target=callback) - thread.start() - self.threads.append(thread) - - for thread in tuple(self.threads): - if not thread.isAlive(): - thread.join() - self.threads.remove(thread) - - self.idle_time += 1 - time.sleep(1) - - except Exception: - self.log.warning( - 'Idle Manager service has failed', exc_info=True - ) - - # Threads don't have their attrs when Qt application already finished - try: - thread_mouse.stop() - thread_mouse.join() - except AttributeError: - pass - - try: - thread_keyboard.stop() - thread_keyboard.join() - except AttributeError: - pass - - self.on_stop() diff --git a/pype/modules/idle_manager/idle_threads.py b/pype/modules/idle_manager/idle_threads.py index ab3f6790e6..7cedf986e6 100644 --- a/pype/modules/idle_manager/idle_threads.py +++ b/pype/modules/idle_manager/idle_threads.py @@ -1,5 +1,10 @@ +import time +import threading + from pynput import mouse, keyboard +from pype.lib import PypeLogger + class MouseThread(mouse.Listener): """Listens user's mouse movement.""" @@ -22,3 +27,71 @@ class KeyboardThread(keyboard.Listener): def on_press(self, key): self.callback() + + +class IdleManagerThread(threading.Thread): + def __init__(self, module, *args, **kwargs): + super(IdleManagerThread, self).__init__(*args, **kwargs) + self.log = PypeLogger.get_logger(self.__class__.__name__) + self.module = module + self.threads = [] + self.is_running = False + self.idle_time = 0 + + def stop(self): + self.is_running = False + + def reset_time(self): + self.idle_time = 0 + + @property + def time_callbacks(self): + return self.module.time_callbacks + + def on_stop(self): + self.is_running = False + self.log.info("IdleManagerThread has stopped") + self.module.on_thread_stop() + + def run(self): + self.log.info("IdleManagerThread has started") + self.is_running = True + thread_mouse = MouseThread(self.reset_time) + thread_keyboard = KeyboardThread(self.reset_time) + thread_mouse.start() + thread_keyboard.start() + try: + while self.is_running: + if self.idle_time in self.time_callbacks: + for callback in self.time_callbacks[self.idle_time]: + thread = threading.Thread(target=callback) + thread.start() + self.threads.append(thread) + + for thread in tuple(self.threads): + if not thread.isAlive(): + thread.join() + self.threads.remove(thread) + + self.idle_time += 1 + time.sleep(1) + + except Exception: + self.log.warning( + 'Idle Manager service has failed', exc_info=True + ) + + # Threads don't have their attrs when Qt application already finished + try: + thread_mouse.stop() + thread_mouse.join() + except AttributeError: + pass + + try: + thread_keyboard.stop() + thread_keyboard.join() + except AttributeError: + pass + + self.on_stop() From c502cc2d1c58384074ce50a8f2599e210ad2203a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:15:13 +0100 Subject: [PATCH 042/295] event sync convert hierarchical values to proper type --- .../event_sync_to_avalon.py | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index d71a94aabf..ba60945968 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -2159,10 +2159,43 @@ class SyncToAvalonEvent(BaseEvent): ftrack_project_id = self.cur_project["id"] + attr_types_by_id = self.cust_attr_types_by_id + convert_types_by_id = {} for attr in hier_attrs: key = attr["key"] if key not in hier_cust_attrs_keys: continue + + type_id = attr["type_id"] + attr_id = attr["id"] + cust_attr_type_name = attr_types_by_id[type_id]["name"] + convert_type = None + if cust_attr_type_name == "text": + convert_type = str + + elif cust_attr_type_name == "boolean": + convert_type = bool + + elif cust_attr_type_name in ( + "date", "expression", "notificationtype", "dynamic enumerator" + ): + pass + + else: + cust_attr_config = json.loads(attr["config"]) + if cust_attr_type_name == "number": + if cust_attr_config["isdecimal"]: + convert_type = float + else: + convert_type = int + + elif cust_attr_type_name == "enumerator": + if cust_attr_config["multiSelect"]: + convert_type = list + else: + convert_type = str + + convert_types_by_id[attr_id] = convert_type entities_dict[ftrack_project_id]["hier_attrs"][key] = ( attr["default"] ) @@ -2173,8 +2206,15 @@ class SyncToAvalonEvent(BaseEvent): if value["value"] is None: continue entity_id = value["entity_id"] - key = hier_attr_key_by_id[value["configuration_id"]] - entities_dict[entity_id]["hier_attrs"][key] = value["value"] + configuration_id = value["configuration_id"] + + convert_type = convert_types_by_id[configuration_id] + key = hier_attr_key_by_id[configuration_id] + + the_value = value["value"] + if convert_type: + the_value = convert_type(the_value) + entities_dict[entity_id]["hier_attrs"][key] = the_value # Get dictionary with not None hierarchical values to pull to childs project_values = {} From 47a7fbe18130359a028946a22e461afb6838dba7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:26:41 +0100 Subject: [PATCH 043/295] implemented function to retrieve python type for passed custom attribute --- pype/modules/ftrack/lib/avalon_sync.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index addc8a4a9c..9aa76539b6 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -119,6 +119,31 @@ def get_pype_attr(session, split_hierarchical=True, query_keys=None): return custom_attributes +def get_python_type_for_custom_attribute(cust_attr, cust_attr_type_name=None): + if cust_attr_type_name is None: + cust_attr_type_name = cust_attr["type"]["name"] + + if cust_attr_type_name == "text": + return str + + if cust_attr_type_name == "boolean": + return bool + + if cust_attr_type_name in ("number", "enumerator"): + cust_attr_config = json.loads(cust_attr["config"]) + if cust_attr_type_name == "number": + if cust_attr_config["isdecimal"]: + return float + return int + + if cust_attr_type_name == "enumerator": + if cust_attr_config["multiSelect"]: + return list + return str + # "date", "expression", "notificationtype", "dynamic enumerator" + return None + + def from_dict_to_set(data, is_project): """ Converts 'data' into $set part of MongoDB update command. From a91c0368e2de1ac0d8aed746ed544bf301269cef Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:27:01 +0100 Subject: [PATCH 044/295] event sync to avalon is using get_python_type_for_custom_attribute --- .../event_sync_to_avalon.py | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index ba60945968..c03abbd52f 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -2169,31 +2169,9 @@ class SyncToAvalonEvent(BaseEvent): type_id = attr["type_id"] attr_id = attr["id"] cust_attr_type_name = attr_types_by_id[type_id]["name"] - convert_type = None - if cust_attr_type_name == "text": - convert_type = str - - elif cust_attr_type_name == "boolean": - convert_type = bool - - elif cust_attr_type_name in ( - "date", "expression", "notificationtype", "dynamic enumerator" - ): - pass - - else: - cust_attr_config = json.loads(attr["config"]) - if cust_attr_type_name == "number": - if cust_attr_config["isdecimal"]: - convert_type = float - else: - convert_type = int - - elif cust_attr_type_name == "enumerator": - if cust_attr_config["multiSelect"]: - convert_type = list - else: - convert_type = str + convert_type = avalon_sync.get_python_type_for_custom_attribute( + attr, cust_attr_type_name + ) convert_types_by_id[attr_id] = convert_type entities_dict[ftrack_project_id]["hier_attrs"][key] = ( From f0f4a1c65bb6b00df5952c8eb07dcaba34cdde70 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:38:55 +0100 Subject: [PATCH 045/295] define query keys --- pype/modules/ftrack/lib/avalon_sync.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 9aa76539b6..d75a6babdd 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -321,6 +321,16 @@ def get_hierarchical_attributes(session, entity, attr_names, attr_defaults={}): class SyncEntitiesFactory: dbcon = AvalonMongoDB() + cust_attr_query_keys = [ + "id", + "key", + "entity_type", + "object_type_id", + "is_hierarchical", + "config", + "default" + ] + project_query = ( "select full_name, name, custom_attributes" ", project_schema._task_type_schema.types.name" @@ -866,7 +876,9 @@ class SyncEntitiesFactory: def set_cutom_attributes(self): self.log.debug("* Preparing custom attributes") # Get custom attributes and values - custom_attrs, hier_attrs = get_pype_attr(self.session) + custom_attrs, hier_attrs = get_pype_attr( + self.session, query_keys=self.cust_attr_query_keys + ) ent_types = self.session.query("select id, name from ObjectType").all() ent_types_by_name = { ent_type["name"]: ent_type["id"] for ent_type in ent_types From c8bc66ae9ed6a220ed5c3657bce6698c190cdf65 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:41:21 +0100 Subject: [PATCH 046/295] sync to avalon action is also using proper value type --- pype/modules/ftrack/lib/avalon_sync.py | 63 ++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index d75a6babdd..2db124235e 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -883,6 +883,14 @@ class SyncEntitiesFactory: ent_types_by_name = { ent_type["name"]: ent_type["id"] for ent_type in ent_types } + # Custom attribute types + cust_attr_types = self.session.query( + "select id, name from CustomAttributeType" + ).all() + cust_attr_type_name_by_id = { + cust_attr_type["id"]: cust_attr_type["name"] + for cust_attr_type in cust_attr_types + } # store default values per entity type attrs_per_entity_type = collections.defaultdict(dict) @@ -892,9 +900,20 @@ class SyncEntitiesFactory: avalon_attrs_ca_id = collections.defaultdict(dict) attribute_key_by_id = {} + convert_types_by_attr_id = {} for cust_attr in custom_attrs: key = cust_attr["key"] - attribute_key_by_id[cust_attr["id"]] = key + attr_id = cust_attr["id"] + type_id = cust_attr["type_id"] + + attribute_key_by_id[attr_id] = key + cust_attr_type_name = cust_attr_type_name_by_id[type_id] + + convert_type = get_python_type_for_custom_attribute( + cust_attr, cust_attr_type_name + ) + convert_types_by_attr_id[attr_id] = convert_type + ca_ent_type = cust_attr["entity_type"] if key.startswith("avalon_"): if ca_ent_type == "show": @@ -988,24 +1007,44 @@ class SyncEntitiesFactory: for item in values["data"]: entity_id = item["entity_id"] - key = attribute_key_by_id[item["configuration_id"]] + attr_id = item["configuration_id"] + key = attribute_key_by_id[attr_id] store_key = "custom_attributes" if key.startswith("avalon_"): store_key = "avalon_attrs" - self.entities_dict[entity_id][store_key][key] = item["value"] + + convert_type = convert_types_by_attr_id[attr_id] + value = item["value"] + if convert_type: + value = convert_type(value) + self.entities_dict[entity_id][store_key][key] = value # process hierarchical attributes - self.set_hierarchical_attribute(hier_attrs, sync_ids) + self.set_hierarchical_attribute( + hier_attrs, sync_ids, cust_attr_type_name_by_id + ) - def set_hierarchical_attribute(self, hier_attrs, sync_ids): + def set_hierarchical_attribute( + self, hier_attrs, sync_ids, cust_attr_type_name_by_id + ): # collect all hierarchical attribute keys # and prepare default values to project attributes_by_key = {} attribute_key_by_id = {} + convert_types_by_attr_id = {} for attr in hier_attrs: key = attr["key"] - attribute_key_by_id[attr["id"]] = key + attr_id = attr["id"] + type_id = attr["type_id"] + attribute_key_by_id[attr_id] = key attributes_by_key[key] = attr + + cust_attr_type_name = cust_attr_type_name_by_id[type_id] + convert_type = get_python_type_for_custom_attribute( + attr, cust_attr_type_name + ) + convert_types_by_attr_id[attr_id] = convert_type + self.hier_cust_attr_ids_by_key[key] = attr["id"] store_key = "hier_attrs" @@ -1040,7 +1079,7 @@ class SyncEntitiesFactory: else: prepare_dict[key] = None - for id, entity_dict in self.entities_dict.items(): + for entity_dict in self.entities_dict.values(): # Skip project because has stored defaults at the moment if entity_dict["entity_type"] == "project": continue @@ -1078,8 +1117,14 @@ class SyncEntitiesFactory: or (isinstance(value, (tuple, list)) and not value) ): continue + + attr_id = item["configuration_id"] + convert_type = convert_types_by_attr_id[attr_id] + if convert_type: + value = convert_type(value) + entity_id = item["entity_id"] - key = attribute_key_by_id[item["configuration_id"]] + key = attribute_key_by_id[attr_id] if key.startswith("avalon_"): store_key = "avalon_attrs" avalon_hier.append(key) @@ -2436,7 +2481,7 @@ class SyncEntitiesFactory: if new_entity_id not in p_chilren: self.entities_dict[parent_id]["children"].append(new_entity_id) - cust_attr, hier_attrs = get_pype_attr(self.session) + cust_attr, _ = get_pype_attr(self.session) for _attr in cust_attr: key = _attr["key"] if key not in av_entity["data"]: From c8f1e14bb8453dbb845b1169bb44dcf2c441374b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 15:43:26 +0100 Subject: [PATCH 047/295] added some docstrings --- pype/modules/ftrack/lib/avalon_sync.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 2db124235e..ff305fe17b 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -120,6 +120,14 @@ def get_pype_attr(session, split_hierarchical=True, query_keys=None): def get_python_type_for_custom_attribute(cust_attr, cust_attr_type_name=None): + """Python type that should value of custom attribute have. + + This function is mainly for number type which is always float from ftrack. + + Returns: + type: Python type which call be called on object to convert the object + to the type or None if can't figure out. + """ if cust_attr_type_name is None: cust_attr_type_name = cust_attr["type"]["name"] From df12e9a112fa6c17d180238ec9d7525f100d4c21 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 16:13:47 +0100 Subject: [PATCH 048/295] fixed and made faster new entity creation --- .../event_sync_to_avalon.py | 59 +++------ pype/modules/ftrack/lib/avalon_sync.py | 125 +++++++++--------- 2 files changed, 81 insertions(+), 103 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index c03abbd52f..4b0b96f166 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1248,48 +1248,18 @@ class SyncToAvalonEvent(BaseEvent): return final_entity - def get_cust_attr_values(self, entity, keys=None): + def get_cust_attr_values(self, entity): output = {} custom_attrs, hier_attrs = self.avalon_cust_attrs - not_processed_keys = True - if keys: - not_processed_keys = [k for k in keys] + # Notmal custom attributes - processed_keys = [] for attr in custom_attrs: - if not not_processed_keys: - break key = attr["key"] - if key in processed_keys: - continue + if key in entity["custom_attributes"]: + output[key] = entity["custom_attributes"][key] - if key not in entity["custom_attributes"]: - continue - - if keys: - if key not in keys: - continue - else: - not_processed_keys.remove(key) - - output[key] = entity["custom_attributes"][key] - processed_keys.append(key) - - if not not_processed_keys: - return output - - # Hierarchical cust attrs - hier_keys = [] - defaults = {} - for attr in hier_attrs: - key = attr["key"] - if keys and key not in keys: - continue - hier_keys.append(key) - defaults[key] = attr["default"] - - hier_values = avalon_sync.get_hierarchical_attributes( - self.process_session, entity, hier_keys, defaults + hier_values = avalon_sync.get_hierarchical_attributes_values( + self.process_session, entity, hier_attrs ) for key, val in hier_values.items(): if key == CUST_ATTR_ID_KEY: @@ -2147,7 +2117,8 @@ class SyncToAvalonEvent(BaseEvent): queries = [{ "action": "query", "expression": ( - "select value, entity_id from CustomAttributeValue " + "select value, entity_id, configuration_id" + " from CustomAttributeValue " "where entity_id in ({}) and configuration_id in ({})" ).format(entity_ids_joined, attributes_joined) }] @@ -2180,19 +2151,19 @@ class SyncToAvalonEvent(BaseEvent): # PREPARE DATA BEFORE THIS avalon_hier = [] - for value in values["data"]: - if value["value"] is None: + for item in values["data"]: + value = item["value"] + if value is None: continue - entity_id = value["entity_id"] - configuration_id = value["configuration_id"] + entity_id = item["entity_id"] + configuration_id = item["configuration_id"] convert_type = convert_types_by_id[configuration_id] key = hier_attr_key_by_id[configuration_id] - the_value = value["value"] if convert_type: - the_value = convert_type(the_value) - entities_dict[entity_id]["hier_attrs"][key] = the_value + value = convert_type(value) + entities_dict[entity_id]["hier_attrs"][key] = value # Get dictionary with not None hierarchical values to pull to childs project_values = {} diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index ff305fe17b..a6151bfba9 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -249,79 +249,84 @@ def get_project_apps(in_app_list): return apps, warnings -def get_hierarchical_attributes(session, entity, attr_names, attr_defaults={}): - entity_ids = [] - if entity.entity_type.lower() == "project": - entity_ids.append(entity["id"]) - else: - typed_context = session.query(( - "select ancestors.id, project from TypedContext where id is \"{}\"" - ).format(entity["id"])).one() - entity_ids.append(typed_context["id"]) - entity_ids.extend( - [ent["id"] for ent in reversed(typed_context["ancestors"])] +def get_hierarchical_attributes_values( + session, entity, hier_attrs, cust_attr_types=None +): + if not cust_attr_types: + cust_attr_types = session.query( + "select id, name from CustomAttributeType" + ).all() + + cust_attr_name_by_id = { + cust_attr_type["id"]: cust_attr_type["name"] + for cust_attr_type in cust_attr_types + } + # Hierarchical cust attrs + attr_key_by_id = {} + convert_types_by_attr_id = {} + defaults = {} + for attr in hier_attrs: + attr_id = attr["id"] + key = attr["key"] + type_id = attr["type_id"] + + attr_key_by_id[attr_id] = key + defaults[key] = attr["default"] + + cust_attr_type_name = cust_attr_name_by_id[type_id] + convert_type = get_python_type_for_custom_attribute( + attr, cust_attr_type_name ) - entity_ids.append(typed_context["project"]["id"]) + convert_types_by_attr_id[attr_id] = convert_type - missing_defaults = [] - for attr_name in attr_names: - if attr_name not in attr_defaults: - missing_defaults.append(attr_name) + entity_ids = [item["id"] for item in entity["link"]] + + join_ent_ids = join_query_keys(entity_ids) + join_attribute_ids = join_query_keys(attr_key_by_id.keys()) - join_ent_ids = ", ".join( - ["\"{}\"".format(entity_id) for entity_id in entity_ids] - ) - join_attribute_names = ", ".join( - ["\"{}\"".format(key) for key in attr_names] - ) queries = [] queries.append({ "action": "query", "expression": ( - "select value, entity_id from CustomAttributeValue " - "where entity_id in ({}) and configuration.key in ({})" - ).format(join_ent_ids, join_attribute_names) + "select value, configuration_id, entity_id" + " from CustomAttributeValue" + " where entity_id in ({}) and configuration_id in ({})" + ).format(join_ent_ids, join_attribute_ids) }) - if not missing_defaults: - if hasattr(session, "call"): - [values] = session.call(queries) - else: - [values] = session._call(queries) + if hasattr(session, "call"): + [values] = session.call(queries) else: - join_missing_names = ", ".join( - ["\"{}\"".format(key) for key in missing_defaults] - ) - queries.append({ - "action": "query", - "expression": ( - "select default from CustomAttributeConfiguration " - "where key in ({})" - ).format(join_missing_names) - }) - - [values, default_values] = session.call(queries) - for default_value in default_values: - key = default_value["data"][0]["key"] - attr_defaults[key] = default_value["data"][0]["default"] + [values] = session._call(queries) hier_values = {} - for key, val in attr_defaults.items(): + for key, val in defaults.items(): hier_values[key] = val if not values["data"]: return hier_values - _hier_values = collections.defaultdict(list) - for value in values["data"]: - key = value["configuration"]["key"] - _hier_values[key].append(value) + values_by_entity_id = collections.defaultdict(dict) + for item in values["data"]: + value = item["value"] + if value is None: + continue - for key, values in _hier_values.items(): - value = sorted( - values, key=lambda value: entity_ids.index(value["entity_id"]) - )[0] - hier_values[key] = value["value"] + attr_id = item["configuration_id"] + + convert_type = convert_types_by_attr_id[attr_id] + if convert_type: + value = convert_type(value) + + key = attr_key_by_id[attr_id] + entity_id = item["entity_id"] + values_by_entity_id[entity_id][key] = value + + for entity_id in entity_ids: + for key in attr_key_by_id.values(): + value = values_by_entity_id[entity_id].get(key) + if value is not None: + hier_values[key] = value return hier_values @@ -999,8 +1004,9 @@ class SyncEntitiesFactory: ]) cust_attr_query = ( - "select value, entity_id from ContextCustomAttributeValue " - "where entity_id in ({}) and configuration_id in ({})" + "select value, configuration_id, entity_id" + " from ContextCustomAttributeValue" + " where entity_id in ({}) and configuration_id in ({})" ) call_expr = [{ "action": "query", @@ -1106,8 +1112,9 @@ class SyncEntitiesFactory: call_expr = [{ "action": "query", "expression": ( - "select value, entity_id from ContextCustomAttributeValue " - "where entity_id in ({}) and configuration_id in ({})" + "select value, entity_id, configuration_id" + " from ContextCustomAttributeValue" + " where entity_id in ({}) and configuration_id in ({})" ).format(entity_ids_joined, attributes_joined) }] if hasattr(self.session, "call"): From 236ad6561783f861d25b56062fc95c4c02995634 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 16:16:39 +0100 Subject: [PATCH 049/295] use precached values --- .../event_handlers_server/event_sync_to_avalon.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 4b0b96f166..be3a15b049 100644 --- a/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1259,13 +1259,17 @@ class SyncToAvalonEvent(BaseEvent): output[key] = entity["custom_attributes"][key] hier_values = avalon_sync.get_hierarchical_attributes_values( - self.process_session, entity, hier_attrs + self.process_session, + entity, + hier_attrs, + self.cust_attr_types_by_id ) for key, val in hier_values.items(): - if key == CUST_ATTR_ID_KEY: - continue output[key] = val + # Make sure mongo id is not set + output.pop(CUST_ATTR_ID_KEY, None) + return output def process_renamed(self): From 202ba646c55c2116cb350dd68ad49d945797754c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:42:24 +0100 Subject: [PATCH 050/295] implemented settings changes interface --- pype/modules/__init__.py | 1 + pype/modules/settings_action.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pype/modules/__init__.py b/pype/modules/__init__.py index 7b945922ea..4b120647e1 100644 --- a/pype/modules/__init__.py +++ b/pype/modules/__init__.py @@ -11,6 +11,7 @@ from .base import ( ) from .settings_action import ( SettingsAction, + ISettingsChangeListener, LocalSettingsAction ) from .webserver import ( diff --git a/pype/modules/settings_action.py b/pype/modules/settings_action.py index aab10e9ebf..2fc59b11c2 100644 --- a/pype/modules/settings_action.py +++ b/pype/modules/settings_action.py @@ -1,6 +1,37 @@ +from abc import ABCMeta, abstractmethod + +import six + from . import PypeModule, ITrayAction +@six.add_metaclass(ABCMeta) +class ISettingsChangeListener: + """Module has plugin paths to return. + + Expected result is dictionary with keys "publish", "create", "load" or + "actions" and values as list or string. + { + "publish": ["path/to/publish_plugins"] + } + """ + @abstractmethod + def on_system_settings_save(self, old_value, new_value, changes): + pass + + @abstractmethod + def on_project_settings_save( + self, old_value, new_value, changes, project_name + ): + pass + + @abstractmethod + def on_project_anatomy_save( + self, old_value, new_value, changes, project_name + ): + pass + + class SettingsAction(PypeModule, ITrayAction): """Action to show Setttings tool.""" name = "settings" From af0736d068e045ed9669953aa33474ea8a9a10bf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:43:19 +0100 Subject: [PATCH 051/295] Ftrack module listens to settings changes --- pype/modules/ftrack/ftrack_module.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/ftrack_module.py b/pype/modules/ftrack/ftrack_module.py index a257ede845..30dcba16b8 100644 --- a/pype/modules/ftrack/ftrack_module.py +++ b/pype/modules/ftrack/ftrack_module.py @@ -1,4 +1,5 @@ import os +import collections from abc import ABCMeta, abstractmethod import six import pype @@ -8,7 +9,8 @@ from pype.modules import ( IPluginPaths, ITimersManager, IUserModule, - ILaunchHookPaths + ILaunchHookPaths, + ISettingsChangeListener ) FTRACK_MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -31,7 +33,8 @@ class FtrackModule( IPluginPaths, ITimersManager, IUserModule, - ILaunchHookPaths + ILaunchHookPaths, + ISettingsChangeListener ): name = "ftrack" @@ -115,6 +118,22 @@ class FtrackModule( if self.tray_module: self.tray_module.changed_user() + def on_system_settings_save(self, *_args, **_kwargs): + """Implementation of ISettingsChangeListener interface.""" + # Ignore + return + + def on_project_settings_save(self, *_args, **_kwargs): + """Implementation of ISettingsChangeListener interface.""" + # Ignore + return + + def on_project_anatomy_save( + self, old_value, new_value, changes, project_name + ): + """Implementation of ISettingsChangeListener interface.""" + return + def tray_init(self): from .tray import FtrackTrayWrapper self.tray_module = FtrackTrayWrapper(self) From 49141bccc641fb00ece49074e8a5ba8d87954759 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:43:35 +0100 Subject: [PATCH 052/295] implemented function to calculate changes --- pype/settings/lib.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index c4238f3ffe..81561b876e 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -70,6 +70,25 @@ def create_local_settings_handler(): return MongoLocalSettingsHandler() +def calculate_changes(old_value, new_value): + changes = {} + for key, value in new_value.items(): + if key not in old_value: + changes[key] = value + continue + + _value = old_value[key] + if isinstance(value, dict) and isinstance(_value, dict): + _changes = calculate_changes(_value, value) + if _changes: + changes[key] = _changes + continue + + if _value != value: + changes[key] = value + return changes + + @require_handler def save_studio_settings(data): return _SETTINGS_HANDLER.save_studio_settings(data) From ce35976cc4541c0dc39c3a17e6ab1b3f4d52aa67 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:43:50 +0100 Subject: [PATCH 053/295] notify pype modules about settings changes --- pype/settings/lib.py | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 81561b876e..55d16b3e6b 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -91,16 +91,82 @@ def calculate_changes(old_value, new_value): @require_handler def save_studio_settings(data): + # Notify Pype modules + from pype.modules import ModulesManager, ISettingsChangeListener + + old_data = get_system_settings() + default_values = get_default_settings()[SYSTEM_SETTINGS_KEY] + new_data = apply_overrides(default_values, copy.deepcopy(data)) + clear_metadata_from_settings(new_data) + + changes = calculate_changes(old_data, new_data) + modules_manager = ModulesManager() + for module in modules_manager.get_enabled_modules(): + if isinstance(module, ISettingsChangeListener): + module.on_system_settings_save(old_data, new_data, changes) + return _SETTINGS_HANDLER.save_studio_settings(data) @require_handler def save_project_settings(project_name, overrides): + # Notify Pype modules + from pype.modules import ModulesManager, ISettingsChangeListener + + default_values = get_default_settings()[PROJECT_SETTINGS_KEY] + if project_name: + old_data = get_project_settings(project_name) + + studio_overrides = get_studio_project_settings_overrides() + studio_values = apply_overrides(default_values, studio_overrides) + clear_metadata_from_settings(studio_values) + new_data = apply_overrides(studio_values, copy.deepcopy(overrides)) + + else: + old_data = get_default_project_settings() + new_data = apply_overrides(default_values, copy.deepcopy(overrides)) + + clear_metadata_from_settings(new_data) + + changes = calculate_changes(old_data, new_data) + modules_manager = ModulesManager() + for module in modules_manager.get_enabled_modules(): + if isinstance(module, ISettingsChangeListener): + module.on_project_settings_save( + old_data, new_data, project_name, changes + ) + return _SETTINGS_HANDLER.save_project_settings(project_name, overrides) @require_handler def save_project_anatomy(project_name, anatomy_data): + # Notify Pype modules + from pype.modules import ModulesManager, ISettingsChangeListener + + default_values = get_default_settings()[PROJECT_ANATOMY_KEY] + if project_name: + old_data = get_anatomy_settings(project_name) + + studio_overrides = get_studio_project_settings_overrides() + studio_values = apply_overrides(default_values, studio_overrides) + clear_metadata_from_settings(studio_values) + new_data = apply_overrides(studio_values, copy.deepcopy(anatomy_data)) + + else: + old_data = get_default_anatomy_settings() + new_data = apply_overrides(default_values, copy.deepcopy(anatomy_data)) + + clear_metadata_from_settings(new_data) + + changes = calculate_changes(old_data, new_data) + modules_manager = ModulesManager() + for module in modules_manager.get_enabled_modules(): + if isinstance(module, ISettingsChangeListener): + module.on_project_anatomy_save( + old_data, new_data, changes, project_name + ) + return _SETTINGS_HANDLER.save_project_anatomy(project_name, anatomy_data) From 7f72d1554867477972a0998ff1eac0535bb551ac Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:44:35 +0100 Subject: [PATCH 054/295] changed key `tools` to `tools_env` --- .../projects_schema/schemas/schema_anatomy_attributes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json index f75319c7e1..7391108a02 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json @@ -67,7 +67,7 @@ }, { "type": "tools-enum", - "key": "tools", + "key": "tools_env", "label": "Tools" } ] From 88369d863c3d38d5043907c5ec40d0f077b62b8a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:45:00 +0100 Subject: [PATCH 055/295] changed defaults settings --- pype/settings/defaults/project_anatomy/attributes.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/settings/defaults/project_anatomy/attributes.json b/pype/settings/defaults/project_anatomy/attributes.json index cc5516fd1f..1d16be42c5 100644 --- a/pype/settings/defaults/project_anatomy/attributes.json +++ b/pype/settings/defaults/project_anatomy/attributes.json @@ -1,5 +1,5 @@ { - "fps": 25, + "fps": 25.0, "frameStart": 1001, "frameEnd": 1001, "clipIn": 1, @@ -8,7 +8,7 @@ "handleEnd": 0, "resolutionWidth": 1920, "resolutionHeight": 1080, - "pixelAspect": 1, + "pixelAspect": 1.0, "applications": [], - "tools": [] + "tools_env": [] } \ No newline at end of file From bfc48ca039cc3af5685aa4d02d87037913804c09 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:45:20 +0100 Subject: [PATCH 056/295] ftrack module has create_ftrack_setting method --- pype/modules/ftrack/ftrack_module.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pype/modules/ftrack/ftrack_module.py b/pype/modules/ftrack/ftrack_module.py index 30dcba16b8..f2f772b6d2 100644 --- a/pype/modules/ftrack/ftrack_module.py +++ b/pype/modules/ftrack/ftrack_module.py @@ -134,6 +134,20 @@ class FtrackModule( """Implementation of ISettingsChangeListener interface.""" return + def create_ftrack_session(self, **session_kwargs): + import ftrack_api + + if "server_url" not in session_kwargs: + session_kwargs["server_url"] = self.ftrack_url + + if "api_key" not in session_kwargs or "api_user" not in session_kwargs: + from .lib import credentials + cred = credentials.get_credentials() + session_kwargs["api_user"] = cred.get("username") + session_kwargs["api_key"] = cred.get("api_key") + + return ftrack_api.Session(**session_kwargs) + def tray_init(self): from .tray import FtrackTrayWrapper self.tray_module = FtrackTrayWrapper(self) From dbe8bd85e9482f78da32c3ccf9599ffd2d57dbd6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 18:45:47 +0100 Subject: [PATCH 057/295] ftrack module updates changes from settings attributes --- pype/modules/ftrack/ftrack_module.py | 52 +++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/ftrack_module.py b/pype/modules/ftrack/ftrack_module.py index f2f772b6d2..7b9d42f6df 100644 --- a/pype/modules/ftrack/ftrack_module.py +++ b/pype/modules/ftrack/ftrack_module.py @@ -132,7 +132,57 @@ class FtrackModule( self, old_value, new_value, changes, project_name ): """Implementation of ISettingsChangeListener interface.""" - return + if not project_name: + return + + attributes_changes = changes.get("attributes") + if not attributes_changes: + return + + import ftrack_api + from pype.modules.ftrack.lib import avalon_sync + + session = self.create_ftrack_session() + project_entity = session.query( + "Project where full_name is \"{}\"".format(project_name) + ).first() + + if not project_entity: + self.log.warning(( + "Ftrack project with names \"{}\" was not found." + " Skipping settings attributes change callback." + )) + return + + project_id = project_entity["id"] + + cust_attr, hier_attr = avalon_sync.get_pype_attr(session) + cust_attr_by_key = {attr["key"]: attr for attr in cust_attr} + hier_attrs_by_key = {attr["key"]: attr for attr in hier_attr} + for key, value in attributes_changes.items(): + configuration = hier_attrs_by_key.get(key) + if not configuration: + configuration = cust_attr_by_key.get(key) + if not configuration: + continue + + # TODO add value validations + # - value type and list items + entity_key = collections.OrderedDict() + entity_key["configuration_id"] = configuration["id"] + entity_key["entity_id"] = project_id + + session.recorded_operations.push( + ftrack_api.operation.UpdateEntityOperation( + "ContextCustomAttributeValue", + entity_key, + "value", + ftrack_api.symbol.NOT_SET, + value + + ) + ) + session.commit() def create_ftrack_session(self, **session_kwargs): import ftrack_api From 48981b67a36b6152226f5b58b2d37a9aff030726 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Mar 2021 19:14:14 +0100 Subject: [PATCH 058/295] fix anatomy overrides --- pype/settings/lib.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 55d16b3e6b..89e662ee18 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -638,11 +638,7 @@ def get_default_anatomy_settings(clear_metadata=True): # TODO uncomment and remove hotfix result when overrides of anatomy # are stored correctly. - # result = apply_overrides(default_values, studio_values) - result = copy.deepcopy(default_values) - if studio_values: - for key, value in studio_values.items(): - result[key] = value + result = apply_overrides(default_values, studio_values) if clear_metadata: clear_metadata_from_settings(result) local_settings = get_local_settings() @@ -662,8 +658,10 @@ def get_anatomy_settings(project_name, site_name=None, exclude_locals=False): project_overrides = get_project_anatomy_overrides( project_name ) - - result = apply_overrides(studio_overrides, project_overrides) + result = copy.deepcopy(studio_overrides) + if project_overrides: + for key, value in project_overrides.items(): + result[key] = value clear_metadata_from_settings(result) From 4fc12b8c089c31eab6e49998291a163081a42939 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 22 Mar 2021 09:33:10 +0100 Subject: [PATCH 059/295] convert #1067 to 3.0 --- pype/hosts/maya/plugins/publish/extract_playblast.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/hosts/maya/plugins/publish/extract_playblast.py b/pype/hosts/maya/plugins/publish/extract_playblast.py index 99411e7f53..8402e41285 100644 --- a/pype/hosts/maya/plugins/publish/extract_playblast.py +++ b/pype/hosts/maya/plugins/publish/extract_playblast.py @@ -118,7 +118,8 @@ class ExtractPlayblast(pype.api.Extractor): tags.append("delete") # Add camera node name to representation data - camera_node_name = pm.ls(camera)[0].getTransform().getName() + camera_node_name = pm.ls(camera)[0].getTransform().name() + representation = { 'name': 'png', From 89ee780d79d12cebdc1f70480f8d562cd2cfee9d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 09:54:52 +0100 Subject: [PATCH 060/295] raw json cares about value types --- pype/settings/entities/input_entities.py | 21 +++++++++++++++++++-- pype/settings/entities/schemas/README.md | 10 +++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index c26cb249a6..40d1595f5a 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -380,13 +380,30 @@ class RawJsonEntity(InputEntity): def _item_initalization(self): # Schema must define if valid value is dict or list - self.valid_value_types = (list, dict) - self.value_on_not_set = {} + is_list = self.schema_data.get("is_list", False) + if is_list: + valid_value_types = (list, ) + value_on_not_set = [] + else: + valid_value_types = (dict, ) + value_on_not_set = {} + + self._is_list = is_list + self.valid_value_types = valid_value_types + self.value_on_not_set = value_on_not_set self.default_metadata = {} self.studio_override_metadata = {} self.project_override_metadata = {} + @property + def is_list(self): + return self._is_list + + @property + def is_dict(self): + return not self._is_list + def set(self, value): self._validate_value_type(value) diff --git a/pype/settings/entities/schemas/README.md b/pype/settings/entities/schemas/README.md index 80125d4b1b..e92ba8918f 100644 --- a/pype/settings/entities/schemas/README.md +++ b/pype/settings/entities/schemas/README.md @@ -235,13 +235,17 @@ ### raw-json - a little bit enhanced text input for raw json - has validations of json format - - empty value is invalid value, always must be at least `{}` of `[]` - + - empty value is invalid value, always must be json serializable + - valid value types are list `[]` and dictionary `{}` +- schema also defines valid value type + - by default it is dictionary + - to be able use list it is required to define `is_list` to `true` ``` { "type": "raw-json", "key": "profiles", - "label": "Extract Review profiles" + "label": "Extract Review profiles", + "is_list": true } ``` From 0c23cf0c19c9c9408b4f02800f6a33de336b7e2e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 09:55:27 +0100 Subject: [PATCH 061/295] fixed list items in schemas --- .../schemas/projects_schema/schemas/schema_maya_publish.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index bb0e162c04..623658b7a2 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -274,7 +274,8 @@ { "type": "raw-json", "key": "bake_attributes", - "label": "Bake Attributes" + "label": "Bake Attributes", + "is_list": true } ] }, From 9f04cd627cf41b587fd23a628900cbb5bc96eb29 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 09:55:46 +0100 Subject: [PATCH 062/295] raw json widget also validate value types --- .../tools/settings/settings/widgets/item_widgets.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_widgets.py b/pype/tools/settings/settings/widgets/item_widgets.py index 7cfcd84488..ef4b98e1d0 100644 --- a/pype/tools/settings/settings/widgets/item_widgets.py +++ b/pype/tools/settings/settings/widgets/item_widgets.py @@ -366,7 +366,7 @@ class NumberWidget(InputWidget): class RawJsonInput(QtWidgets.QPlainTextEdit): tab_length = 4 - def __init__(self, *args, **kwargs): + def __init__(self, valid_type, *args, **kwargs): super(RawJsonInput, self).__init__(*args, **kwargs) self.setObjectName("RawJsonInput") self.setTabStopDistance( @@ -374,6 +374,7 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): self.font() ).horizontalAdvance(" ") * self.tab_length ) + self.valid_type = valid_type def sizeHint(self): document = self.document() @@ -403,8 +404,8 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): def has_invalid_value(self): try: - self.json_value() - return False + value = self.json_value() + return not isinstance(value, self.valid_type) except Exception: return True @@ -415,7 +416,11 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): class RawJsonWidget(InputWidget): def _add_inputs_to_layout(self): - self.input_field = RawJsonInput(self.content_widget) + if self.entity.is_list: + valid_type = list + else: + valid_type = dict + self.input_field = RawJsonInput(valid_type, self.content_widget) self.input_field.setSizePolicy( QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding From f4a3f43088623ad7809d61181a72a5226fdae4cb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 10:21:28 +0100 Subject: [PATCH 063/295] application arguments are separated --- .../host_settings/template_host_variant.json | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json index 244b9c1f56..53652fd192 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json @@ -43,8 +43,36 @@ "key": "executables", "label": "Executables", "multiplatform": "{multiplatform}", - "multipath": "{multipath_executables}", - "with_arguments": true + "multipath": "{multipath_executables}" + }, + { + "type":"separator" + }, + { + "type": "dict", + "key": "arguments", + "label": "Arguments", + "use_label_wrap": false, + "children": [ + { + "key": "windows", + "label": "Windows", + "type": "list", + "object_type": "text" + }, + { + "key": "linux", + "label": "Linux", + "type": "list", + "object_type": "text" + }, + { + "key": "darwin", + "label": "MacOS", + "type": "list", + "object_type": "text" + } + ] }, { "key": "environment", From ea75b495a0b8256099bee3b070659cdcf1c40d38 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 10:51:38 +0100 Subject: [PATCH 064/295] removed with_arguments key from path schema --- pype/settings/entities/input_entities.py | 9 ++----- pype/settings/entities/item_entities.py | 15 +++-------- .../settings/settings/widgets/item_widgets.py | 27 +++---------------- 3 files changed, 9 insertions(+), 42 deletions(-) diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index c26cb249a6..1afeb9f311 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -366,13 +366,8 @@ class PathInput(InputEntity): schema_types = ["path-input"] def _item_initalization(self): - self.with_arguments = self.schema_data.get("with_arguments", False) - if self.with_arguments: - self.valid_value_types = (list, ) - self.value_on_not_set = ["", ""] - else: - self.valid_value_types = (STRING_TYPE, ) - self.value_on_not_set = "" + self.valid_value_types = (STRING_TYPE, ) + self.value_on_not_set = "" class RawJsonEntity(InputEntity): diff --git a/pype/settings/entities/item_entities.py b/pype/settings/entities/item_entities.py index 11e43e4fa6..42374c350c 100644 --- a/pype/settings/entities/item_entities.py +++ b/pype/settings/entities/item_entities.py @@ -53,15 +53,13 @@ class PathEntity(ItemEntity): self.multiplatform = self.schema_data.get("multiplatform", False) self.multipath = self.schema_data.get("multipath", False) - self.with_arguments = self.schema_data.get("with_arguments", False) # Create child object if not self.multiplatform and not self.multipath: valid_value_types = (STRING_TYPE, ) item_schema = { "type": "path-input", - "key": self.key, - "with_arguments": self.with_arguments + "key": self.key } elif not self.multiplatform: @@ -69,10 +67,7 @@ class PathEntity(ItemEntity): item_schema = { "type": "list", "key": self.key, - "object_type": { - "type": "path-input", - "with_arguments": self.with_arguments - } + "object_type": "path-input" } else: @@ -91,13 +86,9 @@ class PathEntity(ItemEntity): } if self.multipath: child_item["type"] = "list" - child_item["object_type"] = { - "type": "path-input", - "with_arguments": self.with_arguments - } + child_item["object_type"] = "path-input" else: child_item["type"] = "path-input" - child_item["with_arguments"] = self.with_arguments item_schema["children"].append(child_item) diff --git a/pype/tools/settings/settings/widgets/item_widgets.py b/pype/tools/settings/settings/widgets/item_widgets.py index 7cfcd84488..d7d6b8ab34 100644 --- a/pype/tools/settings/settings/widgets/item_widgets.py +++ b/pype/tools/settings/settings/widgets/item_widgets.py @@ -623,40 +623,21 @@ class PathWidget(BaseWidget): class PathInputWidget(InputWidget): def _add_inputs_to_layout(self): self.input_field = QtWidgets.QLineEdit(self.content_widget) - self.args_input_field = None - if self.entity.with_arguments: - self.input_field.setPlaceholderText("Executable path") - self.args_input_field = QtWidgets.QLineEdit(self) - self.args_input_field.setPlaceholderText("Arguments") + self.input_field.setPlaceholderText("Executable path") self.setFocusProxy(self.input_field) - self.content_layout.addWidget(self.input_field, 8) + self.content_layout.addWidget(self.input_field) self.input_field.textChanged.connect(self._on_value_change) - if self.args_input_field: - self.content_layout.addWidget(self.args_input_field, 2) - self.args_input_field.textChanged.connect(self._on_value_change) - def _on_entity_change(self): if self.entity.value != self.input_value(): self.set_entity_value() def set_entity_value(self): - value = self.entity.value - args = "" - if isinstance(value, list): - value, args = value - self.input_field.setText(value) - if self.args_input_field: - self.args_input_field.setText(args) + self.input_field.setText(self.entity.value) def input_value(self): - path_value = self.input_field.text() - if self.entity.with_arguments: - value = [path_value, self.args_input_field.text()] - else: - value = path_value - return value + return self.input_field.text() def _on_value_change(self): if self.ignore_input_changes: From 8b86b0634c555fddc2f7fd02c9626471b2ec52fa Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 10:52:25 +0100 Subject: [PATCH 065/295] fixed SystemSettings initialization in project settings root --- pype/settings/entities/root_entities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index b4dc667826..d1f86666c7 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -596,7 +596,7 @@ class ProjectSettings(RootEntity): def system_settings_entity(self): output = self._system_settings_entity if output is None: - output = SystemSettings() + output = SystemSettings(set_studio_state=False) self._system_settings_entity = output if self.override_state is OverrideState.DEFAULTS: From d46f09615aa7871d26b1699ac07bdeb869c8d399 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 10:52:38 +0100 Subject: [PATCH 066/295] changed order of platforms --- .../host_settings/template_host_variant.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json index 53652fd192..ba009cf094 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json @@ -61,14 +61,14 @@ "object_type": "text" }, { - "key": "linux", - "label": "Linux", + "key": "darwin", + "label": "MacOS", "type": "list", "object_type": "text" }, { - "key": "darwin", - "label": "MacOS", + "key": "linux", + "label": "Linux", "type": "list", "object_type": "text" } From bf5dce7ff7205f000b8c38b3b9ab652d1fe71996 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 10:52:48 +0100 Subject: [PATCH 067/295] resaved executables and arguments --- .../system_settings/applications.json | 555 +++++++++++------- 1 file changed, 354 insertions(+), 201 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index b78d23f6ff..4a13cf78f6 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -37,19 +37,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2020\\bin\\maya.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2020\\bin\\maya.exe" ], "darwin": [], "linux": [ - [ - "/usr/autodesk/maya2020/bin/maya", - "" - ] + "/usr/autodesk/maya2020/bin/maya" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2020", "__environment_keys__": { @@ -66,19 +65,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2019\\bin\\maya.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2019\\bin\\maya.exe" ], "darwin": [], "linux": [ - [ - "/usr/autodesk/maya2019/bin/maya", - "" - ] + "/usr/autodesk/maya2019/bin/maya" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2019", "__environment_keys__": { @@ -95,19 +93,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2017\\bin\\maya.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2018\\bin\\maya.exe" ], "darwin": [], "linux": [ - [ - "/usr/autodesk/maya2018/bin/maya", - "" - ] + "/usr/autodesk/maya2018/bin/maya" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2018", "__environment_keys__": { @@ -159,14 +156,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2020\\bin\\mayabatch.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2020\\bin\\mayabatch.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2020", "__environment_keys__": { @@ -183,14 +182,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2019\\bin\\mayabatch.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2019\\bin\\mayabatch.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2019", "__environment_keys__": { @@ -207,14 +208,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Autodesk\\Maya2018\\bin\\mayabatch.exe", - "" - ] + "C:\\Program Files\\Autodesk\\Maya2018\\bin\\mayabatch.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "MAYA_VERSION": "2018", "__environment_keys__": { @@ -257,19 +260,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe", - "" - ] + "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.2v3Nuke12.2", - "" - ] + "/usr/local/Nuke12.2v3Nuke12.2" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "nuke_12.2": [] @@ -283,19 +285,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe", - "" - ] + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.0v1/Nuke12.0", - "" - ] + "/usr/local/Nuke12.0v1/Nuke12.0" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "nuke_12.0": [] @@ -309,19 +310,18 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe", - "" - ] + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke11.3v5/Nuke11.3", - "" - ] + "/usr/local/Nuke11.3v5/Nuke11.3" ] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "nuke_11.3": [] @@ -335,14 +335,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe", - "" - ] + "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "nuke_11.2": [] @@ -382,17 +384,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe", - "--nukex" - ] + "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.2v3Nuke12.2", - "--nukex" - ] + "/usr/local/Nuke12.2v3Nuke12.2" + ] + }, + "arguments": { + "windows": [ + "--nukex" + ], + "darwin": [ + "--nukex" + ], + "linux": [ + "--nukex" ] }, "environment": { @@ -408,17 +415,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe", - "--nukex" - ] + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.0v1/Nuke12.0", - "--nukex" - ] + "/usr/local/Nuke12.0v1/Nuke12.0" + ] + }, + "arguments": { + "windows": [ + "--nukex" + ], + "darwin": [ + "--nukex" + ], + "linux": [ + "--nukex" ] }, "environment": { @@ -434,17 +446,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe", - "--nukex" - ] + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke11.3v5/Nuke11.3", - "--nukex" - ] + "/usr/local/Nuke11.3v5/Nuke11.3" + ] + }, + "arguments": { + "windows": [ + "--nukex" + ], + "darwin": [ + "--nukex" + ], + "linux": [ + "--nukex" ] }, "environment": { @@ -460,14 +477,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe", - "--nukex" - ] + "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [ + "--nukex" + ], + "darwin": [ + "--nukex" + ], + "linux": [ + "--nukex" + ] + }, "environment": { "__environment_keys__": { "nukex_11.2": [] @@ -509,17 +534,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe", - "--studio" - ] + "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.2v3Nuke12.2", - "--studio" - ] + "/usr/local/Nuke12.2v3Nuke12.2" + ] + }, + "arguments": { + "windows": [ + "--studio" + ], + "darwin": [ + "--studio" + ], + "linux": [ + "--studio" ] }, "environment": { @@ -535,17 +565,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe", - "--studio" - ] + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.0v1/Nuke12.0", - "--studio" - ] + "/usr/local/Nuke12.0v1/Nuke12.0" + ] + }, + "arguments": { + "windows": [ + "--studio" + ], + "darwin": [ + "--studio" + ], + "linux": [ + "--studio" ] }, "environment": { @@ -561,17 +596,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe", - "--studio" - ] + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke11.3v5/Nuke11.3", - "--studio" - ] + "/usr/local/Nuke11.3v5/Nuke11.3" + ] + }, + "arguments": { + "windows": [ + "--studio" + ], + "darwin": [ + "--studio" + ], + "linux": [ + "--studio" ] }, "environment": { @@ -590,6 +630,17 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [ + "--studio" + ], + "darwin": [ + "--studio" + ], + "linux": [ + "--studio" + ] + }, "environment": { "__environment_keys__": { "nukestudio_11.2": [] @@ -631,17 +682,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe", - "--hiero" - ] + "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.2v3Nuke12.2", - "--hiero" - ] + "/usr/local/Nuke12.2v3Nuke12.2" + ] + }, + "arguments": { + "windows": [ + "--hiero" + ], + "darwin": [ + "--hiero" + ], + "linux": [ + "--hiero" ] }, "environment": { @@ -657,17 +713,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe", - "--hiero" - ] + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke12.0v1/Nuke12.0", - "--hiero" - ] + "/usr/local/Nuke12.0v1/Nuke12.0" + ] + }, + "arguments": { + "windows": [ + "--hiero" + ], + "darwin": [ + "--hiero" + ], + "linux": [ + "--hiero" ] }, "environment": { @@ -683,17 +744,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe", - "--hiero" - ] + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" ], "darwin": [], "linux": [ - [ - "/usr/local/Nuke11.3v5/Nuke11.3", - "--hiero" - ] + "/usr/local/Nuke11.3v5/Nuke11.3" + ] + }, + "arguments": { + "windows": [ + "--hiero" + ], + "darwin": [ + "--hiero" + ], + "linux": [ + "--hiero" ] }, "environment": { @@ -709,14 +775,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe", - "--hiero" - ] + "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [ + "--hiero" + ], + "darwin": [ + "--hiero" + ], + "linux": [ + "--hiero" + ] + }, "environment": { "__environment_keys__": { "hiero_11.2": [] @@ -775,6 +849,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "fusion_16": [] @@ -788,14 +867,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Blackmagic Design\\Fusion 9\\Fusion.exe", - "" - ] + "C:\\Program Files\\Blackmagic Design\\Fusion 9\\Fusion.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "fusion_9": [] @@ -869,14 +950,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe", - "" - ] + "C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "resolve_16": [] @@ -919,6 +1002,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "houdini_18": [] @@ -935,6 +1023,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "houdini_17": [] @@ -971,14 +1064,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe", - "--python-use-system-env" - ] + "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [ + "--python-use-system-env" + ], + "darwin": [ + "--python-use-system-env" + ], + "linux": [ + "--python-use-system-env" + ] + }, "environment": { "__environment_keys__": { "blender_2.90": [] @@ -992,14 +1093,22 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Blender Foundation\\Blender 2.83\\blender.exe", - "--python-use-system-env" - ] + "C:\\Program Files\\Blender Foundation\\Blender 2.83\\blender.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [ + "--python-use-system-env" + ], + "darwin": [ + "--python-use-system-env" + ], + "linux": [ + "--python-use-system-env" + ] + }, "environment": { "__environment_keys__": { "blender_2.83": [] @@ -1034,6 +1143,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "harmony_20": [] @@ -1048,13 +1162,15 @@ "executables": { "windows": [], "darwin": [ - [ - "/Applications/Toon Boom Harmony 17 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium", - "" - ] + "/Applications/Toon Boom Harmony 17 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" ], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "harmony_17": [] @@ -1084,18 +1200,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 (64bits)\\TVPaint Animation 11 (64bits).exe", - "" - ], - [ - "C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 Pro (64bits) (DEMO)\\TVPaint Animation 11 Pro (64bits) (DEMO).exe", - "" - ] + "C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 (64bits)\\TVPaint Animation 11 (64bits).exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "tvpaint_Animation 11 (64bits)": [] @@ -1109,14 +1223,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files (x86)\\TVPaint Developpement\\TVPaint Animation 11 (32bits)\\TVPaint Animation 11 (32bits).exe", - "" - ] + "C:\\Program Files (x86)\\TVPaint Developpement\\TVPaint Animation 11 (32bits)\\TVPaint Animation 11 (32bits).exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "tvpaint_Animation 11 (32bits)": [] @@ -1152,14 +1268,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Adobe\\Adobe Photoshop 2020\\Photoshop.exe", - "" - ] + "C:\\Program Files\\Adobe\\Adobe Photoshop 2020\\Photoshop.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "photoshop_2020": [] @@ -1173,14 +1291,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Photoshop.exe", - "" - ] + "C:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Photoshop.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "photoshop_2021": [] @@ -1216,14 +1336,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2020\\Support Files\\AfterFX.exe", - "" - ] + "" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "aftereffects_2020": [] @@ -1237,14 +1359,16 @@ "icon": "", "executables": { "windows": [ - [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2021\\Support Files\\AfterFX.exe", - "" - ] + "C:\\Program Files\\Adobe\\Adobe After Effects 2021\\Support Files\\AfterFX.exe" ], "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "aftereffects_2021": [] @@ -1272,10 +1396,12 @@ "label": "", "variant_label": "Local", "icon": "{}/app_icons/celaction_local.png", - "executables": [ - "", - "" - ], + "executables": "", + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "celation_Local": [] @@ -1287,10 +1413,12 @@ "label": "", "variant_label": "Pulblish", "icon": "", - "executables": [ - "", - "" - ], + "executables": "", + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "celation_Publish": [] @@ -1327,6 +1455,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "unreal_4.24": [] @@ -1353,6 +1486,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "python_Python 3.7": [] @@ -1369,6 +1507,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "python_Python 2.7": [] @@ -1385,6 +1528,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "terminal_Terminal": [] @@ -1414,6 +1562,11 @@ "darwin": [], "linux": [] }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, "environment": { "__environment_keys__": { "djvview_1.1": [] @@ -1422,4 +1575,4 @@ } } } -} \ No newline at end of file +} From a844b966ac817c61672f3e63a27ce9b286d1fe5d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 11:15:15 +0100 Subject: [PATCH 068/295] changed how arguments are prepared for launch context --- pype/lib/applications.py | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 0b1f45f2f1..abaecf1e9c 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -210,32 +210,16 @@ class ApplicationTool: class ApplicationExecutable: def __init__(self, executable): - default_launch_args = [] - executable_path = None - if isinstance(executable, str): - executable_path = executable - - elif isinstance(executable, list): - for arg in executable: - if arg: - if executable_path is None: - executable_path = arg - else: - default_launch_args.append(arg) - - self.executable_path = executable_path - self.default_launch_args = default_launch_args - - def __iter__(self): - yield self._realpath() - for arg in self.default_launch_args: - yield arg + self.executable_path = executable def __str__(self): return self.executable_path + def __repr__(self): + return "<{}> {}".format(self.__class__.__name__, self.executable_path) + def as_args(self): - return list(self) + return [self.executable_path] def _realpath(self): """Check if path is valid executable path.""" @@ -293,11 +277,19 @@ class Application: elif isinstance(_executables, dict): _executables = _executables.get(platform.system().lower()) or [] + _arguments = app_data["arguments"] + if not _arguments: + _arguments = [] + + elif isinstance(_arguments, dict): + _arguments = _arguments.get(platform.system().lower()) or [] + executables = [] for executable in _executables: executables.append(ApplicationExecutable(executable)) self.executables = executables + self.arguments = _arguments @property def full_label(self): @@ -503,6 +495,7 @@ class ApplicationLaunchContext: # subprocess.Popen launch arguments (first argument in constructor) self.launch_args = executable.as_args() + self.launch_args.extend(application.arguments) # Handle launch environemtns env = self.data.pop("env", None) From 15677f56fca5b085ac766485571a65e8d607eebf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 11:15:34 +0100 Subject: [PATCH 069/295] fixed local settings --- pype/tools/settings/local_settings/apps_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/local_settings/apps_widget.py b/pype/tools/settings/local_settings/apps_widget.py index d63cd6a834..bc27a3c1c4 100644 --- a/pype/tools/settings/local_settings/apps_widget.py +++ b/pype/tools/settings/local_settings/apps_widget.py @@ -56,7 +56,7 @@ class AppVariantWidget(QtWidgets.QWidget): for item in studio_executables: path_widget = QtWidgets.QLineEdit(content_widget) - path_widget.setText(item.value[0]) + path_widget.setText(item.value) path_widget.setEnabled(False) content_layout.addWidget(path_widget) From e22fb7b89c7919cfc70f94b6a9adf47c27053913 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 11:16:21 +0100 Subject: [PATCH 070/295] fixed app definition --- pype/settings/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 48e6ca395c..936784f04e 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -502,7 +502,7 @@ class MongoSettingsHandler(SettingsHandler): if not application: continue if isinstance(application, six.string_types): - applications.append({application: application}) + applications.append({"name": application}) new_data["apps"] = applications From d3515e6015dbc2c7305edc55926f140b6f573d34 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 11:25:22 +0100 Subject: [PATCH 071/295] hound fix --- pype/settings/entities/item_entities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/entities/item_entities.py b/pype/settings/entities/item_entities.py index 42374c350c..ebaacb193e 100644 --- a/pype/settings/entities/item_entities.py +++ b/pype/settings/entities/item_entities.py @@ -67,7 +67,7 @@ class PathEntity(ItemEntity): item_schema = { "type": "list", "key": self.key, - "object_type": "path-input" + "object_type": "path-input" } else: From dd51ccdd6831f6eb76e4602c4947e86ddc308eb0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:00:29 +0100 Subject: [PATCH 072/295] short name is by default empty string --- pype/modules/ftrack/lib/avalon_sync.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index a6151bfba9..ccde69eef4 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -1215,11 +1215,6 @@ class SyncEntitiesFactory: ) def prepare_ftrack_ent_data(self): - project_name = self.entities_dict[self.ft_project_id]["name"] - project_anatomy_data = get_anatomy_settings(project_name) - - task_type_mapping = project_anatomy_data["tasks"] - not_set_ids = [] for id, entity_dict in self.entities_dict.items(): entity = entity_dict["entity"] @@ -1258,10 +1253,11 @@ class SyncEntitiesFactory: tasks = {} for task_type in task_types: task_type_name = task_type["name"] - task_type_def = task_type_mapping.get(task_type_name) or {} - short_name = task_type_def.get("short_name") + # Set short name to empty string + # QUESTION Maybe better would be to lower and remove spaces + # from task type name. tasks[task_type_name] = { - "short_name": short_name or task_type_name + "short_name": "" } self.entities_dict[id]["final_entity"]["config"] = { "tasks": tasks, From 0ae39b54b3c37336dffc743dfc30d16c0184f82b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 22 Mar 2021 12:18:41 +0100 Subject: [PATCH 073/295] add nukex to python2 vendor prehook --- pype/hooks/pre_python2_vendor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hooks/pre_python2_vendor.py b/pype/hooks/pre_python2_vendor.py index 070e671db0..6f34e44132 100644 --- a/pype/hooks/pre_python2_vendor.py +++ b/pype/hooks/pre_python2_vendor.py @@ -6,7 +6,7 @@ class PrePython2Vendor(PreLaunchHook): """Prepend python 2 dependencies for py2 hosts.""" # WARNING This hook will probably be deprecated in Pype 3 - kept for test order = 10 - app_groups = ["hiero", "nuke"] + app_groups = ["hiero", "nuke", "nukex"] def execute(self): # Prepare vendor dir path From c24823b90548b70b909197c3d906af9df2a62dee Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:33:56 +0100 Subject: [PATCH 074/295] sync to avalon creates anatomy data if are not set --- pype/modules/ftrack/lib/avalon_sync.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index ccde69eef4..970a270290 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -14,7 +14,11 @@ else: from avalon.api import AvalonMongoDB import avalon -from pype.api import Logger, Anatomy, get_anatomy_settings +from pype.api import ( + Logger, + Anatomy, + get_anatomy_settings +) from bson.objectid import ObjectId from bson.errors import InvalidId @@ -1237,6 +1241,7 @@ class SyncEntitiesFactory: data[key] = val if id == self.ft_project_id: + project_name = entity["full_name"] data["code"] = entity["name"] self.entities_dict[id]["final_entity"]["data"] = data self.entities_dict[id]["final_entity"]["type"] = "project" @@ -1259,10 +1264,23 @@ class SyncEntitiesFactory: tasks[task_type_name] = { "short_name": "" } - self.entities_dict[id]["final_entity"]["config"] = { + + current_project_anatomy_data = get_anatomy_settings( + project_name, exclude_locals=True + ) + + project_config = { "tasks": tasks, "apps": proj_apps } + for key, value in current_project_anatomy_data.items(): + if key in project_config or key == "attributes": + continue + project_config[key] = value + + self.entities_dict[id]["final_entity"]["config"] = ( + project_config + ) continue ent_path_items = [ent["name"] for ent in entity["link"]] From a5ad0e831ab6d8243d9fd9c740eeccff7b6b8a22 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:45:13 +0100 Subject: [PATCH 075/295] added some docstrings --- pype/settings/lib.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 89e662ee18..9dc23e6ddf 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -91,6 +91,19 @@ def calculate_changes(old_value, new_value): @require_handler def save_studio_settings(data): + """Save studio overrides of system settings. + + Triggers callbacks on modules that want to know about system settings + changes. + + Callbacks are triggered on all modules. They must check if their enabled + value has changed. + + For saving of data cares registered Settings handler. + + Args: + data(dict): Overrides data with metadata defying studio overrides. + """ # Notify Pype modules from pype.modules import ModulesManager, ISettingsChangeListener @@ -110,6 +123,18 @@ def save_studio_settings(data): @require_handler def save_project_settings(project_name, overrides): + """Save studio overrides of project settings. + + Old value, new value and changes are passed to enabled modules that want to + know about settings changes. + + For saving of data cares registered Settings handler. + + Args: + project_name (str): Project name for which overrides are passed. + Default project's value is None. + overrides(dict): Overrides data with metadata defying studio overrides. + """ # Notify Pype modules from pype.modules import ModulesManager, ISettingsChangeListener @@ -141,6 +166,18 @@ def save_project_settings(project_name, overrides): @require_handler def save_project_anatomy(project_name, anatomy_data): + """Save studio overrides of project anatomy. + + Old value, new value and changes are passed to enabled modules that want to + know about settings changes. + + For saving of data cares registered Settings handler. + + Args: + project_name (str): Project name for which overrides are passed. + Default project's value is None. + overrides(dict): Overrides data with metadata defying studio overrides. + """ # Notify Pype modules from pype.modules import ModulesManager, ISettingsChangeListener From 77627a167cfc8180e40ff04bf31746aeea33ae8d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:53:51 +0100 Subject: [PATCH 076/295] ModulesManager can accept different settings data --- pype/modules/base.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pype/modules/base.py b/pype/modules/base.py index 03a5965841..47c7de9d50 100644 --- a/pype/modules/base.py +++ b/pype/modules/base.py @@ -285,12 +285,20 @@ class ITrayService(ITrayModule): class ModulesManager: + """Manager of Pype modules helps to load and prepare them to work. + + Args: + modules_settings(dict): To be able create module manager with specified + data. For settings changes callbacks and testing purposes. + """ # Helper attributes for report _report_total_key = "Total" - def __init__(self): + def __init__(self, _system_settings=None): self.log = logging.getLogger(self.__class__.__name__) + self._system_settings = _system_settings + self.modules = [] self.modules_by_id = {} self.modules_by_name = {} @@ -304,7 +312,11 @@ class ModulesManager: """Import and initialize modules.""" self.log.debug("*** Pype modules initialization.") # Prepare settings for modules - modules_settings = get_system_settings()["modules"] + if self._system_settings is None: + system_settings = get_system_settings() + else: + system_settings = self._system_settings + modules_settings = system_settings["modules"] report = {} time_start = time.time() From 9abb71962e0b9dd8ced8eb151b261b2b9965ca0f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:54:04 +0100 Subject: [PATCH 077/295] pass new data to create modules manager --- pype/settings/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 9dc23e6ddf..1aa8c11eda 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -113,7 +113,7 @@ def save_studio_settings(data): clear_metadata_from_settings(new_data) changes = calculate_changes(old_data, new_data) - modules_manager = ModulesManager() + modules_manager = ModulesManager(_system_settings=new_data) for module in modules_manager.get_enabled_modules(): if isinstance(module, ISettingsChangeListener): module.on_system_settings_save(old_data, new_data, changes) From 7d8d7f913c9c5fa5f3be185c356ae3732f4ddcb0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 12:58:55 +0100 Subject: [PATCH 078/295] fix system settings attribute --- pype/modules/base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pype/modules/base.py b/pype/modules/base.py index 47c7de9d50..fe68c14705 100644 --- a/pype/modules/base.py +++ b/pype/modules/base.py @@ -312,10 +312,9 @@ class ModulesManager: """Import and initialize modules.""" self.log.debug("*** Pype modules initialization.") # Prepare settings for modules - if self._system_settings is None: + system_settings = getattr(self, "_system_settings", None) + if system_settings is None: system_settings = get_system_settings() - else: - system_settings = self._system_settings modules_settings = system_settings["modules"] report = {} From bfea62c9391fdf71c7051b6c377162f01d03a193 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 13:19:06 +0100 Subject: [PATCH 079/295] fix site settings --- pype/settings/lib.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 1aa8c11eda..bf38b051bc 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -538,7 +538,10 @@ def apply_local_settings_on_anatomy_settings( # Get active site from settings if site_name is None: - project_settings = get_project_settings(project_name) + if project_name: + project_settings = get_project_settings(project_name) + else: + project_settings = get_default_project_settings() site_name = ( project_settings["global"]["sync_server"]["config"]["active_site"] ) From 27c6613718981f47db8816a79913574e77faae94 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 13:19:32 +0100 Subject: [PATCH 080/295] added ability to exclude locals on studio settings getters --- pype/settings/lib.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index bf38b051bc..9cb0bc9ecb 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -148,7 +148,7 @@ def save_project_settings(project_name, overrides): new_data = apply_overrides(studio_values, copy.deepcopy(overrides)) else: - old_data = get_default_project_settings() + old_data = get_default_project_settings(exclude_locals=True) new_data = apply_overrides(default_values, copy.deepcopy(overrides)) clear_metadata_from_settings(new_data) @@ -191,7 +191,7 @@ def save_project_anatomy(project_name, anatomy_data): new_data = apply_overrides(studio_values, copy.deepcopy(anatomy_data)) else: - old_data = get_default_anatomy_settings() + old_data = get_default_anatomy_settings(exclude_locals=True) new_data = apply_overrides(default_values, copy.deepcopy(anatomy_data)) clear_metadata_from_settings(new_data) @@ -659,19 +659,22 @@ def get_system_settings(clear_metadata=True): return result -def get_default_project_settings(clear_metadata=True): +def get_default_project_settings(clear_metadata=True, exclude_locals=False): """Project settings with applied studio's default project overrides.""" default_values = get_default_settings()[PROJECT_SETTINGS_KEY] studio_values = get_studio_project_settings_overrides() result = apply_overrides(default_values, studio_values) if clear_metadata: clear_metadata_from_settings(result) - local_settings = get_local_settings() - apply_local_settings_on_project_settings(result, local_settings, None) + if not exclude_locals: + local_settings = get_local_settings() + apply_local_settings_on_project_settings( + result, local_settings, None + ) return result -def get_default_anatomy_settings(clear_metadata=True): +def get_default_anatomy_settings(clear_metadata=True, exclude_locals=False): """Project anatomy data with applied studio's default project overrides.""" default_values = get_default_settings()[PROJECT_ANATOMY_KEY] studio_values = get_studio_project_anatomy_overrides() @@ -681,8 +684,11 @@ def get_default_anatomy_settings(clear_metadata=True): result = apply_overrides(default_values, studio_values) if clear_metadata: clear_metadata_from_settings(result) - local_settings = get_local_settings() - apply_local_settings_on_anatomy_settings(result, local_settings, None) + if not exclude_locals: + local_settings = get_local_settings() + apply_local_settings_on_anatomy_settings( + result, local_settings, None + ) return result From 7c88137dea845b65f53f26612c3709245327c4f3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 13:24:33 +0100 Subject: [PATCH 081/295] fixed updates --- pype/settings/handlers.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 936784f04e..f2b857dd8c 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -492,9 +492,6 @@ class MongoSettingsHandler(SettingsHandler): continue update_dict_data[key] = value - if update_dict_data: - update_dict["data"] = update_dict_data - update_dict_config = {} applications = [] @@ -512,16 +509,23 @@ class MongoSettingsHandler(SettingsHandler): continue update_dict_config[key] = value - if update_dict_config: - update_dict["config"] = update_dict_config - - if not update_dict: + if not update_dict_data and not update_dict_config: return - _update_dict = self.prepare_mongo_update_dict(update_dict) + data_changes = self.prepare_mongo_update_dict(update_dict_data) + + set_dict = {} + for key, value in data_changes.items(): + new_key = "data.{}".format(key) + set_dict[new_key] = value + + for key, value in update_dict_config.items(): + new_key = "config.{}".format(key) + set_dict[new_key] = value + collection.update_one( {"type": "project"}, - {"$set": _update_dict} + {"$set": set_dict} ) def _save_project_data(self, project_name, doc_type, data_cache): From 94a729e9937b0244e0916b03ce8c9f3f274ddb96 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 22 Mar 2021 13:31:21 +0100 Subject: [PATCH 082/295] hound fix --- pype/settings/handlers.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index f2b857dd8c..78bfd6cc3f 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -476,9 +476,6 @@ class MongoSettingsHandler(SettingsHandler): " Create project first." ).format(project_name)) - # Update dictionary of changes that will be changed in mongo - update_dict = {} - # Project's data update_dict_data = {} project_doc_data = project_doc.get("data") or {} @@ -514,18 +511,19 @@ class MongoSettingsHandler(SettingsHandler): data_changes = self.prepare_mongo_update_dict(update_dict_data) - set_dict = {} + # Update dictionary of changes that will be changed in mongo + update_dict = {} for key, value in data_changes.items(): new_key = "data.{}".format(key) - set_dict[new_key] = value + update_dict[new_key] = value for key, value in update_dict_config.items(): new_key = "config.{}".format(key) - set_dict[new_key] = value + update_dict[new_key] = value collection.update_one( {"type": "project"}, - {"$set": set_dict} + {"$set": update_dict} ) def _save_project_data(self, project_name, doc_type, data_cache): From 57447f2bfcb3a06d8a93e12527d641b4662cf256 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 17:13:00 +0100 Subject: [PATCH 083/295] numbers can be converted to string for text input and enum --- pype/settings/entities/enum_entity.py | 2 ++ pype/settings/entities/input_entities.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index f2831c78dc..66bfb67df9 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -50,6 +50,8 @@ class EnumEntity(InputEntity): if self.multiselection: if isinstance(value, (set, tuple)): return list(value) + elif isinstance(value, (int, float)): + return str(value) return NOT_SET def set(self, value): diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index 2ed397dad9..641da93733 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -369,6 +369,12 @@ class TextEntity(InputEntity): self.multiline = self.schema_data.get("multiline", False) self.placeholder_text = self.schema_data.get("placeholder") + def _convert_to_valid_type(self, value): + # Allow numbers converted to string + if isinstance(value, (int, float)): + return str(value) + return NOT_SET + class PathInput(InputEntity): schema_types = ["path-input"] From 5bdfc29bb614c63d58a2d8f299473087af92358d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 17:13:29 +0100 Subject: [PATCH 084/295] value type of enum must always be string --- pype/settings/entities/enum_entity.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 66bfb67df9..94a995ee08 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -1,5 +1,8 @@ from .input_entities import InputEntity -from .lib import NOT_SET +from .lib import ( + NOT_SET, + STRING_TYPE +) class EnumEntity(InputEntity): @@ -21,13 +24,12 @@ class EnumEntity(InputEntity): self.valid_value_types = (list, ) self.value_on_not_set = [] else: - valid_value_types = set() for key in valid_keys: if self.value_on_not_set is NOT_SET: self.value_on_not_set = key - valid_value_types.add(type(key)) + break - self.valid_value_types = tuple(valid_value_types) + self.valid_value_types = (STRING_TYPE, ) # GUI attribute self.placeholder = self.schema_data.get("placeholder") @@ -42,6 +44,12 @@ class EnumEntity(InputEntity): self.path, key ) ) + if not isinstance(key, STRING_TYPE): + raise ValueError( + "{}: Key \"{}\" has invalid type {}, expected {}.".format( + self.path, key, type(key), STRING_TYPE + ) + ) enum_keys.add(key) super(EnumEntity, self).schema_validations() From 4c89adebeb026a58a79f24f7bec5687d49e454e2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 17:13:36 +0100 Subject: [PATCH 085/295] added path to exception --- pype/settings/entities/enum_entity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 94a995ee08..e5d2097443 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -72,8 +72,8 @@ class EnumEntity(InputEntity): for item in check_values: if item not in self.valid_keys: raise ValueError( - "Invalid value \"{}\". Expected: {}".format( - item, self.valid_keys + "{} Invalid value \"{}\". Expected: {}".format( + self.path, item, self.valid_keys ) ) self._current_value = new_value From 42752c46487649ab0bf0d163192b5a6fba7bfb76 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 17:47:25 +0100 Subject: [PATCH 086/295] using specific exceptions for schema errors --- pype/settings/entities/base_entity.py | 47 ++++++++++--------- .../entities/dict_immutable_keys_entity.py | 22 +++++---- .../entities/dict_mutable_keys_entity.py | 10 ++-- pype/settings/entities/enum_entity.py | 28 ++++++----- pype/settings/entities/exceptions.py | 34 +++++++++----- pype/settings/entities/input_entities.py | 14 +++--- pype/settings/entities/item_entities.py | 7 +-- pype/settings/entities/list_entity.py | 9 ++-- pype/settings/entities/root_entities.py | 6 ++- 9 files changed, 101 insertions(+), 76 deletions(-) diff --git a/pype/settings/entities/base_entity.py b/pype/settings/entities/base_entity.py index 33abee227a..c01fca6a4e 100644 --- a/pype/settings/entities/base_entity.py +++ b/pype/settings/entities/base_entity.py @@ -10,7 +10,8 @@ from .lib import ( from .exceptions import ( InvalidValueType, - SchemeGroupHierarchyBug + SchemeGroupHierarchyBug, + EntitySchemaError ) from pype.lib import PypeLogger @@ -215,49 +216,48 @@ class BaseItemEntity(BaseEntity): """ # Entity must have defined valid value types. if self.valid_value_types is NOT_SET: - raise ValueError("Attribute `valid_value_types` is not filled.") + raise EntitySchemaError( + self, "Attribute `valid_value_types` is not filled." + ) # Check if entity has defined key when is required. if self.require_key and not self.key: - error_msg = "{}: Missing \"key\" in schema data. {}".format( - self.path, str(self.schema_data).replace("'", '"') + error_msg = "Missing \"key\" in schema data. {}".format( + str(self.schema_data).replace("'", '"') ) - raise KeyError(error_msg) + raise EntitySchemaError(self, error_msg) # Group entity must have defined label. (UI specific) # QUESTION this should not be required? if not self.label and self.is_group: - raise ValueError( - "{}: Item is set as `is_group` but has empty `label`.".format( - self.path - ) + raise EntitySchemaError( + self, "Item is set as `is_group` but has empty `label`." ) # Group item can be only once in on hierarchy branch. if self.is_group and self.group_item: - raise SchemeGroupHierarchyBug(self.path) + raise SchemeGroupHierarchyBug(self) # Validate that env group entities will be stored into file. # - env group entities must store metadata which is not possible if # metadata would be outside of file if not self.file_item and self.is_env_group: - raise ValueError(( - "{}: Environment item is not inside file" + reason = ( + "Environment item is not inside file" " item so can't store metadata for defaults." - ).format(self.path)) + ) + raise EntitySchemaError(self, reason) # Dynamic items must not have defined labels. (UI specific) if self.label and self.is_dynamic_item: - raise ValueError(( - "{}: Item has set label but is used as dynamic item." - ).format(self.path)) + raise EntitySchemaError( + self, "Item has set label but is used as dynamic item." + ) # Dynamic items or items in dynamic item must not have set `is_group` if self.is_group and (self.is_dynamic_item or self.is_in_dynamic_item): - raise ValueError( - "{} Dynamic entity has set `is_group` to true.".format( - self.path - ) + raise EntitySchemaError( + self, "Dynamic entity has set `is_group` to true." ) @abstractmethod @@ -818,10 +818,11 @@ class ItemEntity(BaseItemEntity): def schema_validations(self): if not self.label and self.use_label_wrap: - raise ValueError(( - "{} Entity has set `use_label_wrap` to true but" + reason = ( + "Entity has set `use_label_wrap` to true but" " does not have set `label`." - ).format(self.path)) + ) + raise EntitySchemaError(self, reason) super(ItemEntity, self).schema_validations() diff --git a/pype/settings/entities/dict_immutable_keys_entity.py b/pype/settings/entities/dict_immutable_keys_entity.py index d797320583..f062138151 100644 --- a/pype/settings/entities/dict_immutable_keys_entity.py +++ b/pype/settings/entities/dict_immutable_keys_entity.py @@ -15,7 +15,10 @@ from . import ( BoolEntity, GUIEntity ) -from .exceptions import SchemaDuplicatedKeys +from .exceptions import ( + SchemaDuplicatedKeys, + EntitySchemaError +) class DictImmutableKeysEntity(ItemEntity): @@ -83,20 +86,21 @@ class DictImmutableKeysEntity(ItemEntity): elif child_entity.key not in children_keys: children_keys.add(child_entity.key) else: - raise SchemaDuplicatedKeys(self.path, child_entity.key) + raise SchemaDuplicatedKeys(self, child_entity.key) if self.checkbox_key: checkbox_child = self.non_gui_children.get(self.checkbox_key) if not checkbox_child: - raise ValueError( - "{}: Checkbox children \"{}\" was not found.".format( - self.path, self.checkbox_key - ) + reason = "Checkbox children \"{}\" was not found.".format( + self.checkbox_key ) + raise EntitySchemaError(self, reason) + if not isinstance(checkbox_child, BoolEntity): - raise TypeError(( - "{}: Checkbox children \"{}\" is not `boolean` type." - ).format(self.path, self.checkbox_key)) + reason = "Checkbox children \"{}\" is not `boolean` type.".format( + self.checkbox_key + ) + raise EntitySchemaError(self, reason) super(DictImmutableKeysEntity, self).schema_validations() # Trigger schema validation on children entities diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index c314242bf9..7005d346c1 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -8,7 +8,8 @@ from . import EndpointEntity from .exceptions import ( DefaultsNotDefined, StudioDefaultsNotDefined, - RequiredKeyModified + RequiredKeyModified, + EntitySchemaError ) from pype.settings.constants import ( METADATA_KEYS, @@ -213,10 +214,11 @@ class DictMutableKeysEntity(EndpointEntity): # TODO Ability to store labels should be defined with different key if self.collapsible_key and not self.file_item: - raise ValueError(( - "{}: Modifiable dictionary with collapsible keys is not under" + reason = ( + "Modifiable dictionary with collapsible keys is not under" " file item so can't store metadata." - ).format(self.path)) + ) + raise EntitySchemaError(self, reason) for child_obj in self.children_by_key.values(): child_obj.schema_validations() diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index e5d2097443..b7b7d1cf4d 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -1,4 +1,5 @@ from .input_entities import InputEntity +from .exceptions import EntitySchemaError from .lib import ( NOT_SET, STRING_TYPE @@ -35,24 +36,29 @@ class EnumEntity(InputEntity): self.placeholder = self.schema_data.get("placeholder") def schema_validations(self): + if not isinstance(self.enum_items, list): + raise EntitySchemaError( + self, "Enum item must have defined `enum_items` as list." + ) + enum_keys = set() for item in self.enum_items: key = tuple(item.keys())[0] if key in enum_keys: - raise ValueError( - "{}: Key \"{}\" is more than once in enum items.".format( - self.path, key - ) - ) - if not isinstance(key, STRING_TYPE): - raise ValueError( - "{}: Key \"{}\" has invalid type {}, expected {}.".format( - self.path, key, type(key), STRING_TYPE - ) + reason = "Key \"{}\" is more than once in enum items.".format( + key ) + raise EntitySchemaError(self, reason) + enum_keys.add(key) - super(EnumEntity, self).schema_validations() + if not isinstance(key, STRING_TYPE): + reason = "Key \"{}\" has invalid type {}, expected {}.".format( + key, type(key), STRING_TYPE + ) + raise EntitySchemaError(self, reason) + + super(BaseEnumEntity, self).schema_validations() def _convert_to_valid_type(self, value): if self.multiselection: diff --git a/pype/settings/entities/exceptions.py b/pype/settings/entities/exceptions.py index 7080a9b187..2c3b262ff1 100644 --- a/pype/settings/entities/exceptions.py +++ b/pype/settings/entities/exceptions.py @@ -38,6 +38,23 @@ class SchemaError(Exception): pass +class EntitySchemaError(SchemaError): + def __init__(self, entity, reason): + self.entity = entity + self.reason = reason + msg = "{} {} - {}".format(entity.__class__, entity.path, reason) + super(EntitySchemaError, self).__init__(msg) + + +class SchemeGroupHierarchyBug(EntitySchemaError): + def __init__(self, entity): + reason = ( + "Items with attribute \"is_group\" can't have another item with" + " \"is_group\" attribute as child." + ) + super(SchemeGroupHierarchyBug, self).__init__(entity, reason) + + class SchemaMissingFileInfo(SchemaError): def __init__(self, invalid): full_path_keys = [] @@ -51,22 +68,13 @@ class SchemaMissingFileInfo(SchemaError): super(SchemaMissingFileInfo, self).__init__(msg) -class SchemeGroupHierarchyBug(SchemaError): - def __init__(self, entity_path): - msg = ( - "Items with attribute \"is_group\" can't have another item with" - " \"is_group\" attribute as child. Error happened in entity: {}" - ).format(entity_path) - super(SchemeGroupHierarchyBug, self).__init__(msg) - - class SchemaDuplicatedKeys(SchemaError): - def __init__(self, entity_path, key): + def __init__(self, entity, key): msg = ( "Schema item contain duplicated key \"{}\" in" - " one hierarchy level. {}" - ).format(key, entity_path) - super(SchemaDuplicatedKeys, self).__init__(msg) + " one hierarchy level." + ).format(key) + super(SchemaDuplicatedKeys, self).__init__(entity, msg) class SchemaDuplicatedEnvGroupKeys(SchemaError): diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index 641da93733..a1beaef9f4 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -9,7 +9,8 @@ from .lib import ( ) from .exceptions import ( DefaultsNotDefined, - StudioDefaultsNotDefined + StudioDefaultsNotDefined, + EntitySchemaError ) from pype.settings.constants import ( @@ -39,11 +40,10 @@ class EndpointEntity(ItemEntity): """Validation of entity schema and schema hierarchy.""" # Default value when even defaults are not filled must be set if self.value_on_not_set is NOT_SET: - raise ValueError( - "Attribute `value_on_not_set` is not filled. {}".format( - self.__class__.__name__ - ) + reason = "Attribute `value_on_not_set` is not filled. {}".format( + self.__class__.__name__ ) + raise EntitySchemaError(self, reason) super(EndpointEntity, self).schema_validations() @@ -105,9 +105,7 @@ class InputEntity(EndpointEntity): def schema_validations(self): # Input entity must have file parent. if not self.file_item: - raise ValueError( - "{}: Missing parent file entity.".format(self.path) - ) + raise EntitySchemaError(self, "Missing parent file entity.") super(InputEntity, self).schema_validations() diff --git a/pype/settings/entities/item_entities.py b/pype/settings/entities/item_entities.py index 2edd3dad77..56e7d1c7b2 100644 --- a/pype/settings/entities/item_entities.py +++ b/pype/settings/entities/item_entities.py @@ -5,7 +5,8 @@ from .lib import ( ) from .exceptions import ( DefaultsNotDefined, - StudioDefaultsNotDefined + StudioDefaultsNotDefined, + EntitySchemaError ) from .base_entity import ItemEntity @@ -204,8 +205,8 @@ class ListStrictEntity(ItemEntity): def schema_validations(self): # List entity must have file parent. if not self.file_item and not self.is_file: - raise ValueError( - "{}: Missing file entity in hierarchy.".format(self.path) + raise EntitySchemaError( + self, "Missing file entity in hierarchy." ) super(ListStrictEntity, self).schema_validations() diff --git a/pype/settings/entities/list_entity.py b/pype/settings/entities/list_entity.py index 814086fe0f..c6155b78f8 100644 --- a/pype/settings/entities/list_entity.py +++ b/pype/settings/entities/list_entity.py @@ -9,7 +9,8 @@ from .lib import ( ) from .exceptions import ( DefaultsNotDefined, - StudioDefaultsNotDefined + StudioDefaultsNotDefined, + EntitySchemaError ) @@ -153,16 +154,18 @@ class ListEntity(EndpointEntity): super(ListEntity, self).schema_validations() if self.is_dynamic_item and self.use_label_wrap: - raise ValueError( + reason = ( "`ListWidget` can't have set `use_label_wrap` to True and" " be used as widget at the same time." ) + raise EntitySchemaError(self, reason) if self.use_label_wrap and not self.label: - raise ValueError( + reason = ( "`ListWidget` can't have set `use_label_wrap` to True and" " not have set \"label\" key at the same time." ) + raise EntitySchemaError(self, reason) for child_obj in self.children: child_obj.schema_validations() diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index 74ccb8d17c..89660971f1 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -13,6 +13,7 @@ from .lib import ( get_studio_settings_schema, get_project_settings_schema ) +from .exceptions import EntitySchemaError from pype.settings.constants import ( SYSTEM_SETTINGS_KEY, PROJECT_SETTINGS_KEY, @@ -145,10 +146,11 @@ class RootEntity(BaseItemEntity): def schema_validations(self): for child_entity in self.children: if child_entity.is_group: - raise ValueError(( + reason = ( "Root entity \"{}\" has child with `is_group`" " attribute set to True but root can't save overrides." - ).format(self.__class__.__name__)) + ).format(self.__class__.__name__) + raise EntitySchemaError(self, reason) child_entity.schema_validations() def get_entity_from_path(self, path): From 5c7ea9d9e42b2d1ba8d016cfeadc6b2d2ba608ed Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 17:48:26 +0100 Subject: [PATCH 087/295] enum entity was abstracted to be able do more specific schema validations --- pype/settings/entities/__init__.py | 2 + pype/settings/entities/enum_entity.py | 75 +++++++++++-------- pype/settings/entities/root_entities.py | 3 +- .../settings/settings/widgets/categories.py | 4 +- 4 files changed, 51 insertions(+), 33 deletions(-) diff --git a/pype/settings/entities/__init__.py b/pype/settings/entities/__init__.py index 20e00de4a5..e0910077df 100644 --- a/pype/settings/entities/__init__.py +++ b/pype/settings/entities/__init__.py @@ -96,6 +96,7 @@ from .input_entities import ( ) from .enum_entity import ( + BaseEnumEntity, EnumEntity, AppsEnumEntity, ToolsEnumEntity @@ -141,6 +142,7 @@ __all__ = ( "PathInput", "RawJsonEntity", + "BaseEnumEntity", "EnumEntity", "AppsEnumEntity", "ToolsEnumEntity", diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index b7b7d1cf4d..2dcb1a8935 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -6,34 +6,14 @@ from .lib import ( ) -class EnumEntity(InputEntity): - schema_types = ["enum"] - +class BaseEnumEntity(InputEntity): def _item_initalization(self): - self.multiselection = self.schema_data.get("multiselection", False) - self.enum_items = self.schema_data["enum_items"] - if not self.enum_items: - raise ValueError("Attribute `enum_items` is not defined.") - - valid_keys = set() - for item in self.enum_items: - valid_keys.add(tuple(item.keys())[0]) - - self.valid_keys = valid_keys - - if self.multiselection: - self.valid_value_types = (list, ) - self.value_on_not_set = [] - else: - for key in valid_keys: - if self.value_on_not_set is NOT_SET: - self.value_on_not_set = key - break - - self.valid_value_types = (STRING_TYPE, ) - - # GUI attribute - self.placeholder = self.schema_data.get("placeholder") + self.multiselection = True + self.value_on_not_set = None + self.enum_items = None + self.valid_keys = None + self.valid_value_types = None + self.placeholder = None def schema_validations(self): if not isinstance(self.enum_items, list): @@ -78,7 +58,7 @@ class EnumEntity(InputEntity): for item in check_values: if item not in self.valid_keys: raise ValueError( - "{} Invalid value \"{}\". Expected: {}".format( + "{} Invalid value \"{}\". Expected one of: {}".format( self.path, item, self.valid_keys ) ) @@ -86,7 +66,42 @@ class EnumEntity(InputEntity): self._on_value_change() -class AppsEnumEntity(EnumEntity): +class EnumEntity(BaseEnumEntity): + schema_types = ["enum"] + + def _item_initalization(self): + self.multiselection = self.schema_data.get("multiselection", False) + self.enum_items = self.schema_data.get("enum_items") + + valid_keys = set() + for item in self.enum_items or []: + valid_keys.add(tuple(item.keys())[0]) + + self.valid_keys = valid_keys + + if self.multiselection: + self.valid_value_types = (list, ) + self.value_on_not_set = [] + else: + for key in valid_keys: + if self.value_on_not_set is NOT_SET: + self.value_on_not_set = key + break + + self.valid_value_types = (STRING_TYPE, ) + + # GUI attribute + self.placeholder = self.schema_data.get("placeholder") + + def schema_validations(self): + if not self.enum_items and "enum_items" not in self.schema_data: + raise EntitySchemaError( + self, "Enum item must have defined `enum_items`" + ) + super().schema_validations() + + +class AppsEnumEntity(BaseEnumEntity): schema_types = ["apps-enum"] def _item_initalization(self): @@ -139,7 +154,7 @@ class AppsEnumEntity(EnumEntity): self._current_value = new_value -class ToolsEnumEntity(EnumEntity): +class ToolsEnumEntity(BaseEnumEntity): schema_types = ["tools-enum"] def _item_initalization(self): diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index 89660971f1..82885e8479 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -175,7 +175,8 @@ class RootEntity(BaseItemEntity): entities.BaseItemEntity, entities.ItemEntity, entities.EndpointEntity, - entities.InputEntity + entities.InputEntity, + entities.BaseEnumEntity ) self._loaded_types = {} diff --git a/pype/tools/settings/settings/widgets/categories.py b/pype/tools/settings/settings/widgets/categories.py index 07f7291e91..4cab86c30b 100644 --- a/pype/tools/settings/settings/widgets/categories.py +++ b/pype/tools/settings/settings/widgets/categories.py @@ -15,7 +15,7 @@ from pype.settings.entities import ( NumberEntity, BoolEntity, - EnumEntity, + BaseEnumEntity, TextEntity, PathInput, RawJsonEntity, @@ -112,7 +112,7 @@ class SettingsCategoryWidget(QtWidgets.QWidget): elif isinstance(entity, RawJsonEntity): return RawJsonWidget(*args) - elif isinstance(entity, EnumEntity): + elif isinstance(entity, BaseEnumEntity): return EnumeratorWidget(*args) elif isinstance(entity, PathEntity): From 16e11a29593b9a47c221acb21a7fb4902cd1fbca Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 23 Mar 2021 19:36:28 +0100 Subject: [PATCH 088/295] hound fix --- pype/settings/entities/dict_immutable_keys_entity.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/settings/entities/dict_immutable_keys_entity.py b/pype/settings/entities/dict_immutable_keys_entity.py index f062138151..92a36b7dca 100644 --- a/pype/settings/entities/dict_immutable_keys_entity.py +++ b/pype/settings/entities/dict_immutable_keys_entity.py @@ -97,9 +97,9 @@ class DictImmutableKeysEntity(ItemEntity): raise EntitySchemaError(self, reason) if not isinstance(checkbox_child, BoolEntity): - reason = "Checkbox children \"{}\" is not `boolean` type.".format( - self.checkbox_key - ) + reason = ( + "Checkbox children \"{}\" is not `boolean` type." + ).format(self.checkbox_key) raise EntitySchemaError(self, reason) super(DictImmutableKeysEntity, self).schema_validations() From 771a8e29acc80806c514c5277692238042d2a870 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 24 Mar 2021 10:17:08 +0100 Subject: [PATCH 089/295] rename master version to hero --- pype/lib/avalon_context.py | 2 +- pype/modules/sync_server/tray/app.py | 2 +- .../publish/integrate_master_version.py | 146 +++++++++--------- .../defaults/project_anatomy/templates.json | 6 +- .../defaults/project_settings/global.json | 2 +- .../schemas/schema_anatomy_templates.json | 4 +- .../schemas/schema_global_publish.json | 4 +- ...version-1.0.json => hero_version-1.0.json} | 12 +- test_localsystem.txt | 1 + 9 files changed, 90 insertions(+), 89 deletions(-) rename schema/{master_version-1.0.json => hero_version-1.0.json} (76%) create mode 100644 test_localsystem.txt diff --git a/pype/lib/avalon_context.py b/pype/lib/avalon_context.py index dc0ce9a873..d4daf22142 100644 --- a/pype/lib/avalon_context.py +++ b/pype/lib/avalon_context.py @@ -40,7 +40,7 @@ def is_latest(representation): """ version = avalon.io.find_one({"_id": representation['parent']}) - if version["type"] == "master_version": + if version["type"] == "hero_version": return True # Get highest version under the parent diff --git a/pype/modules/sync_server/tray/app.py b/pype/modules/sync_server/tray/app.py index b28ca0f66e..783f2def1c 100644 --- a/pype/modules/sync_server/tray/app.py +++ b/pype/modules/sync_server/tray/app.py @@ -784,7 +784,7 @@ class SyncRepresentationModel(QtCore.QAbstractTableModel): if context.get("version"): version = "v{:0>3d}".format(context.get("version")) else: - version = "master" + version = "hero" item = self.SyncRepresentation( repre.get("_id"), diff --git a/pype/plugins/publish/integrate_master_version.py b/pype/plugins/publish/integrate_master_version.py index 7d72bb26d4..7709f089fe 100644 --- a/pype/plugins/publish/integrate_master_version.py +++ b/pype/plugins/publish/integrate_master_version.py @@ -10,8 +10,8 @@ from avalon import api, io, schema from avalon.vendor import filelink -class IntegrateMasterVersion(pyblish.api.InstancePlugin): - label = "Integrate Master Version" +class IntegrateHeroVersion(pyblish.api.InstancePlugin): + label = "Integrate Hero Version" # Must happen after IntegrateNew order = pyblish.api.IntegratorOrder + 0.1 @@ -39,7 +39,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): def process(self, instance): self.log.debug( - "--- Integration of Master version for subset `{}` begins.".format( + "--- Integration of Hero version for subset `{}` begins.".format( instance.data.get("subset", str(instance)) ) ) @@ -52,25 +52,25 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): project_name = api.Session["AVALON_PROJECT"] - # TODO raise error if master not set? + # TODO raise error if Hero not set? anatomy = instance.context.data["anatomy"] - if "master" not in anatomy.templates: - self.log.warning("!!! Anatomy does not have set `master` key!") + if "hero" not in anatomy.templates: + self.log.warning("!!! Anatomy does not have set `hero` key!") return - if "path" not in anatomy.templates["master"]: + if "path" not in anatomy.templates["hero"]: self.log.warning(( - "!!! There is not set `path` template in `master` anatomy" + "!!! There is not set `path` template in `hero` anatomy" " for project \"{}\"." ).format(project_name)) return - master_template = anatomy.templates["master"]["path"] - self.log.debug("`Master` template check was successful. `{}`".format( - master_template + hero_template = anatomy.templates["hero"]["path"] + self.log.debug("`hero` template check was successful. `{}`".format( + hero_template )) - master_publish_dir = self.get_publish_dir(instance) + hero_publish_dir = self.get_publish_dir(instance) src_version_entity = instance.data.get("versionEntity") filtered_repre_ids = [] @@ -105,7 +105,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): if not src_version_entity: self.log.warning(( "!!! Can't find origin version in database." - " Skipping Master version publish." + " Skipping hero version publish." )) return @@ -131,7 +131,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): all_repre_file_paths.append(file_path) # TODO this is not best practice of getting resources for publish - # WARNING due to this we must remove all files from master publish dir + # WARNING due to this we must remove all files from hero publish dir instance_publish_dir = os.path.normpath( instance.data["publishDir"] ) @@ -145,13 +145,13 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): continue dst_filepath = file_path.replace( - instance_publish_dir, master_publish_dir + instance_publish_dir, hero_publish_dir ) other_file_paths_mapping.append((file_path, dst_filepath)) # Current version old_version, old_repres = ( - self.current_master_ents(src_version_entity) + self.current_hero_ents(src_version_entity) ) old_repres_by_name = { @@ -163,30 +163,30 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): else: new_version_id = io.ObjectId() - new_master_version = { + new_hero_version = { "_id": new_version_id, "version_id": src_version_entity["_id"], "parent": src_version_entity["parent"], - "type": "master_version", - "schema": "pype:master_version-1.0" + "type": "hero_version", + "schema": "pype:hero_version-1.0" } - schema.validate(new_master_version) + schema.validate(new_hero_version) # Don't make changes in database until everything is O.K. bulk_writes = [] if old_version: - self.log.debug("Replacing old master version.") + self.log.debug("Replacing old hero version.") bulk_writes.append( ReplaceOne( - {"_id": new_master_version["_id"]}, - new_master_version + {"_id": new_hero_version["_id"]}, + new_hero_version ) ) else: - self.log.debug("Creating first master version.") + self.log.debug("Creating first hero version.") bulk_writes.append( - InsertOne(new_master_version) + InsertOne(new_hero_version) ) # Separate old representations into `to replace` and `to delete` @@ -213,21 +213,21 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): repre_name_low = repre["name"].lower() archived_repres_by_name[repre_name_low] = repre - backup_master_publish_dir = None - if os.path.exists(master_publish_dir): - backup_master_publish_dir = master_publish_dir + ".BACKUP" + backup_hero_publish_dir = None + if os.path.exists(hero_publish_dir): + backup_hero_publish_dir = hero_publish_dir + ".BACKUP" max_idx = 10 idx = 0 - _backup_master_publish_dir = backup_master_publish_dir - while os.path.exists(_backup_master_publish_dir): + _backup_hero_publish_dir = backup_hero_publish_dir + while os.path.exists(_backup_hero_publish_dir): self.log.debug(( "Backup folder already exists." " Trying to remove \"{}\"" - ).format(_backup_master_publish_dir)) + ).format(_backup_hero_publish_dir)) try: - shutil.rmtree(_backup_master_publish_dir) - backup_master_publish_dir = _backup_master_publish_dir + shutil.rmtree(_backup_hero_publish_dir) + backup_hero_publish_dir = _backup_hero_publish_dir break except Exception: self.log.info(( @@ -235,11 +235,11 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): " Trying to add index to folder name" )) - _backup_master_publish_dir = ( - backup_master_publish_dir + str(idx) + _backup_hero_publish_dir = ( + backup_hero_publish_dir + str(idx) ) - if not os.path.exists(_backup_master_publish_dir): - backup_master_publish_dir = _backup_master_publish_dir + if not os.path.exists(_backup_hero_publish_dir): + backup_hero_publish_dir = _backup_hero_publish_dir break if idx > max_idx: @@ -251,14 +251,14 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): idx += 1 self.log.debug("Backup folder path is \"{}\"".format( - backup_master_publish_dir + backup_hero_publish_dir )) try: - os.rename(master_publish_dir, backup_master_publish_dir) + os.rename(hero_publish_dir, backup_hero_publish_dir) except PermissionError: raise AssertionError(( - "Could not create master version because it is not" - " possible to replace current master files." + "Could not create hero version because it is not" + " possible to replace current hero files." )) try: src_to_dst_file_paths = [] @@ -275,11 +275,11 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): # Get filled path to repre context anatomy_filled = anatomy.format(anatomy_data) - template_filled = anatomy_filled["master"]["path"] + template_filled = anatomy_filled["hero"]["path"] repre_data = { "path": str(template_filled), - "template": master_template + "template": hero_template } repre_context = template_filled.used_values for key in self.db_representation_context_keys: @@ -293,7 +293,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): # Prepare new repre repre = copy.deepcopy(repre_info["representation"]) - repre["parent"] = new_master_version["_id"] + repre["parent"] = new_hero_version["_id"] repre["context"] = repre_context repre["data"] = repre_data repre.pop("_id", None) @@ -319,7 +319,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): frame_splitter = "_-_FRAME_SPLIT_-_" anatomy_data["frame"] = frame_splitter _anatomy_filled = anatomy.format(anatomy_data) - _template_filled = _anatomy_filled["master"]["path"] + _template_filled = _anatomy_filled["hero"]["path"] head, tail = _template_filled.split(frame_splitter) padding = int( anatomy.templates["render"].get( @@ -338,7 +338,7 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): (src_file, dst_file) ) - # replace original file name with master name in repre doc + # replace original file name with hero name in repre doc for index in range(len(repre.get("files"))): file = repre.get("files")[index] file_name = os.path.basename(file.get('path')) @@ -431,27 +431,27 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): bulk_writes ) - # Remove backuped previous master + # Remove backuped previous hero if ( - backup_master_publish_dir is not None and - os.path.exists(backup_master_publish_dir) + backup_hero_publish_dir is not None and + os.path.exists(backup_hero_publish_dir) ): - shutil.rmtree(backup_master_publish_dir) + shutil.rmtree(backup_hero_publish_dir) except Exception: if ( - backup_master_publish_dir is not None and - os.path.exists(backup_master_publish_dir) + backup_hero_publish_dir is not None and + os.path.exists(backup_hero_publish_dir) ): - os.rename(backup_master_publish_dir, master_publish_dir) + os.rename(backup_hero_publish_dir, hero_publish_dir) self.log.error(( - "!!! Creating of Master version failed." - " Previous master version maybe lost some data!" + "!!! Creating of hero version failed." + " Previous hero version maybe lost some data!" )) raise self.log.debug(( - "--- Master version integration for subset `{}`" + "--- hero version integration for subset `{}`" " seems to be successful." ).format( instance.data.get("subset", str(instance)) @@ -469,9 +469,9 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): anatomy = instance.context.data["anatomy"] template_data = copy.deepcopy(instance.data["anatomyData"]) - if "folder" in anatomy.templates["master"]: + if "folder" in anatomy.templates["hero"]: anatomy_filled = anatomy.format(template_data) - publish_folder = anatomy_filled["master"]["folder"] + publish_folder = anatomy_filled["hero"]["folder"] else: # This is for cases of Deprecated anatomy without `folder` # TODO remove when all clients have solved this issue @@ -488,13 +488,13 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): " key underneath `publish` (in global of for project `{}`)." ).format(project_name)) - file_path = anatomy_filled["master"]["path"] + file_path = anatomy_filled["hero"]["path"] # Directory publish_folder = os.path.dirname(file_path) publish_folder = os.path.normpath(publish_folder) - self.log.debug("Master publish dir: \"{}\"".format(publish_folder)) + self.log.debug("hero publish dir: \"{}\"".format(publish_folder)) return publish_folder @@ -535,33 +535,33 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): if version: return version - def current_master_ents(self, version): - master_version = io.find_one({ + def current_hero_ents(self, version): + hero_version = io.find_one({ "parent": version["parent"], - "type": "master_version" + "type": "hero_version" }) - if not master_version: + if not hero_version: return (None, []) - master_repres = list(io.find({ - "parent": master_version["_id"], + hero_repres = list(io.find({ + "parent": hero_version["_id"], "type": "representation" })) - return (master_version, master_repres) + return (hero_version, hero_repres) def _update_path(self, anatomy, path, src_file, dst_file): """ - Replaces source path with new master path + Replaces source path with new hero path 'path' contains original path with version, must be replaced with - 'master' path (with 'master' label and without version) + 'hero' path (with 'hero' label and without version) Args: anatomy (Anatomy) - to get rootless style of path path (string) - path from DB src_file (string) - original file path - dst_file (string) - master file path + dst_file (string) - hero file path """ _, rootless = anatomy.find_root_template_from_path( dst_file @@ -573,13 +573,13 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin): def _update_hash(self, hash, src_file_name, dst_file): """ - Updates hash value with proper master name + Updates hash value with proper hero name """ src_file_name = self._get_name_without_ext( src_file_name) - master_file_name = self._get_name_without_ext( + hero_file_name = self._get_name_without_ext( dst_file) - return hash.replace(src_file_name, master_file_name) + return hash.replace(src_file_name, hero_file_name) def _get_name_without_ext(self, value): file_name = os.path.basename(value) diff --git a/pype/settings/defaults/project_anatomy/templates.json b/pype/settings/defaults/project_anatomy/templates.json index 862b732846..2b16f59d01 100644 --- a/pype/settings/defaults/project_anatomy/templates.json +++ b/pype/settings/defaults/project_anatomy/templates.json @@ -21,9 +21,9 @@ "path": "{@folder}/{@file}", "thumbnail": "{thumbnail_root}/{project[name]}/{_id}_{thumbnail_type}.{ext}" }, - "master": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/{subset}/master", - "file": "{project[code]}_{asset}_{subset}_master<_{output}><.{frame}>.{ext}", + "hero": { + "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/{subset}/hero", + "file": "{project[code]}_{asset}_{subset}_hero<_{output}><.{frame}>.{ext}", "path": "{@folder}/{@file}" }, "delivery": {}, diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index ada4a6e17c..0bd9c2a3a6 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -1,6 +1,6 @@ { "publish": { - "IntegrateMasterVersion": { + "IntegrateHeroVersion": { "enabled": true }, "ExtractJpegEXR": { diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json index 918d3edba6..a8534e7e29 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json @@ -113,8 +113,8 @@ }, { "type": "dict", - "key": "master", - "label": "Master", + "key": "hero", + "label": "Hero", "children": [ { "type": "text", diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 4045870a9a..32e8c7d1e9 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -8,8 +8,8 @@ "type": "dict", "collapsible": true, "checkbox_key": "enabled", - "key": "IntegrateMasterVersion", - "label": "IntegrateMasterVersion", + "key": "IntegrateHeroVersion", + "label": "IntegrateHeroVersion", "is_group": true, "children": [ { diff --git a/schema/master_version-1.0.json b/schema/hero_version-1.0.json similarity index 76% rename from schema/master_version-1.0.json rename to schema/hero_version-1.0.json index 9dff570b3a..83304ef4d5 100644 --- a/schema/master_version-1.0.json +++ b/schema/hero_version-1.0.json @@ -1,8 +1,8 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:master_version-1.0", - "description": "Master version of asset", + "title": "pype:hero_version-1.0", + "description": "Hero version of asset", "type": "object", @@ -27,14 +27,14 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["avalon-core:master_version-1.0", "pype:master_version-1.0"], - "example": "pype:master_version-1.0" + "enum": ["avalon-core:hero_version-1.0", "pype:hero_version-1.0"], + "example": "pype:hero_version-1.0" }, "type": { "description": "The type of document", "type": "string", - "enum": ["master_version"], - "example": "master_version" + "enum": ["hero_version"], + "example": "hero_version" }, "parent": { "description": "Unique identifier to parent document", diff --git a/test_localsystem.txt b/test_localsystem.txt new file mode 100644 index 0000000000..dde7986af8 --- /dev/null +++ b/test_localsystem.txt @@ -0,0 +1 @@ +I have run From 33f319ddf87ba05b00447eeb5bc025db3690cde3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 12:38:13 +0100 Subject: [PATCH 090/295] opacity has defined min/max and decimals --- .../schemas/schema_global_publish.json | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 4045870a9a..92abe7064e 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -208,17 +208,24 @@ { "type": "number", "key": "font_size", - "label": "Font size" + "label": "Font size", + "minimum": 0 }, { "type": "number", "key": "opacity", - "label": "Font opacity" + "label": "Font opacity", + "decimal": 2, + "maximum": 1, + "minimum": 0 }, { "type": "number", "key": "bg_opacity", - "label": "Background opacity" + "label": "Background opacity", + "decimal": 2, + "maximum": 1, + "minimum": 0 }, { "type": "number", From cf68e071f7486402550f9653cb9191faf024d7b4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 12:38:22 +0100 Subject: [PATCH 091/295] resaved values --- pype/settings/defaults/project_settings/global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index ada4a6e17c..7aab1082fe 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -51,8 +51,8 @@ "enabled": true, "options": { "font_size": 42, - "opacity": 1, - "bg_opacity": 0, + "opacity": 1.0, + "bg_opacity": 0.5, "x_offset": 5, "y_offset": 5, "bg_padding": 5 From 75d96074f3c93fbbe0ca0c6d9401e45d5794e30f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 12:39:01 +0100 Subject: [PATCH 092/295] number entity entity can convert stringified number to to number type --- pype/settings/entities/input_entities.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index a1beaef9f4..921171cfff 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -1,3 +1,4 @@ +import re import copy from abc import abstractmethod @@ -320,6 +321,8 @@ class InputEntity(EndpointEntity): class NumberEntity(InputEntity): schema_types = ["number"] + float_number_regex = re.compile(r"^\d+\.\d+$") + int_number_regex = re.compile(r"^\d+$") def _item_initalization(self): self.minimum = self.schema_data.get("minimum", -99999) @@ -334,15 +337,32 @@ class NumberEntity(InputEntity): self.value_on_not_set = 0 def _convert_to_valid_type(self, value): + if isinstance(value, str): + new_value = None + if self.float_number_regex.match(value): + new_value = float(value) + elif self.int_number_regex.match(value): + new_value = int(value) + + if new_value is not None: + self.log.info("{} - Converted str {} to {} {}".format( + self.path, value, type(new_value).__name__, new_value + )) + value = new_value + if self.decimal: + if isinstance(value, float): + return value if isinstance(value, int): return float(value) else: + if isinstance(value, int): + return value if isinstance(value, float): new_value = int(value) if new_value != value: - self.log.info("Converted float {} to int {}".format( - value, new_value + self.log.info("{} - Converted float {} to int {}".format( + self.path, value, new_value )) return new_value return NOT_SET From 5a07975714acc234a04d19f5c7bf07ede6ef2389 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 12:40:35 +0100 Subject: [PATCH 093/295] moved separator out of options entity top be visible even if options are collapsed --- .../projects_schema/schemas/schema_global_publish.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 92abe7064e..e0ef5ea2e1 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -241,13 +241,12 @@ "type": "number", "key": "bg_padding", "label": "Padding aroung text" - }, - { - "type": "splitter" } ] }, - + { + "type": "separator" + }, { "type": "list", "key": "profiles", From 60e563bf66fd983e0ee122070aab3b26cc1e3c8b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 13:00:38 +0100 Subject: [PATCH 094/295] specify more packages of pywin32 module --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6a86f0f97a..e3be48d6e0 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,12 @@ include_files = [ ] if sys.platform == "win32": - install_requires.append("win32ctypes") + install_requires.extend([ + # `pywin32` packages + "win32ctypes", + "win32comext", + "pythoncom" + ]) build_options = dict( packages=install_requires, From 222c6104105cd153243e5a4499e082f2a815c472 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 15:26:08 +0100 Subject: [PATCH 095/295] fix super call for python 2 compatibility --- pype/settings/entities/enum_entity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 2dcb1a8935..f06ec97f4b 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -98,7 +98,7 @@ class EnumEntity(BaseEnumEntity): raise EntitySchemaError( self, "Enum item must have defined `enum_items`" ) - super().schema_validations() + super(EnumEntity, self).schema_validations() class AppsEnumEntity(BaseEnumEntity): From 9bfaa841a9bf8587b3cf68eba2c4e063ec146186 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 15:44:38 +0100 Subject: [PATCH 096/295] anatomy_keys and attribute_keys are created on demand --- pype/settings/handlers.py | 46 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 78bfd6cc3f..1dae2526f5 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -343,24 +343,11 @@ class MongoSettingsHandler(SettingsHandler): # Get mongo connection from pype.lib import PypeMongoConnection from avalon.api import AvalonMongoDB - from .entities import ProjectSettings settings_collection = PypeMongoConnection.get_mongo_client() - # Prepare anatomy keys and attribute keys - # NOTE this is cached on first import - # - keys may change only on schema change which should not happen - # during production - project_settings_root = ProjectSettings( - reset=False, change_state=False - ) - anatomy_entity = project_settings_root["project_anatomy"] - anatomy_keys = set(anatomy_entity.keys()) - anatomy_keys.remove("attributes") - attribute_keys = set(anatomy_entity["attributes"].keys()) - - self.anatomy_keys = anatomy_keys - self.attribute_keys = attribute_keys + self._anatomy_keys = None + self._attribute_keys = None # TODO prepare version of pype # - pype version should define how are settings saved and loaded @@ -380,6 +367,35 @@ class MongoSettingsHandler(SettingsHandler): self.project_settings_cache = collections.defaultdict(CacheValues) self.project_anatomy_cache = collections.defaultdict(CacheValues) + def _prepare_project_settings_keys(self): + from .entities import ProjectSettings + # Prepare anatomy keys and attribute keys + # NOTE this is cached on first import + # - keys may change only on schema change which should not happen + # during production + project_settings_root = ProjectSettings( + reset=False, change_state=False + ) + anatomy_entity = project_settings_root["project_anatomy"] + anatomy_keys = set(anatomy_entity.keys()) + anatomy_keys.remove("attributes") + attribute_keys = set(anatomy_entity["attributes"].keys()) + + self._anatomy_keys = anatomy_keys + self._attribute_keys = attribute_keys + + @property + def anatomy_keys(self): + if self._anatomy_keys: + self._prepare_project_settings_keys() + return self._anatomy_keys + + @property + def attribute_keys(self): + if self._attribute_keys: + self._prepare_project_settings_keys() + return self._attribute_keys + def save_studio_settings(self, data): """Save studio overrides of system settings. From 0197eaa5d730a2e360d355d58c7ffe4fdb7a1670 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 16:03:25 +0100 Subject: [PATCH 097/295] settings ui can catch exceptions --- pype/settings/entities/__init__.py | 1 + .../settings/settings/widgets/categories.py | 57 ++++++++++++++++--- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/pype/settings/entities/__init__.py b/pype/settings/entities/__init__.py index e0910077df..1cb4be62e7 100644 --- a/pype/settings/entities/__init__.py +++ b/pype/settings/entities/__init__.py @@ -54,6 +54,7 @@ print(system_settings["general"]["studio_name"].value) """ from .exceptions import ( + SchemaError, DefaultsNotDefined, StudioDefaultsNotDefined, InvalidValueType, diff --git a/pype/tools/settings/settings/widgets/categories.py b/pype/tools/settings/settings/widgets/categories.py index 4cab86c30b..d84bf3dc15 100644 --- a/pype/tools/settings/settings/widgets/categories.py +++ b/pype/tools/settings/settings/widgets/categories.py @@ -1,4 +1,6 @@ import os +import sys +import traceback from enum import Enum from Qt import QtWidgets, QtCore, QtGui @@ -21,7 +23,8 @@ from pype.settings.entities import ( RawJsonEntity, DefaultsNotDefined, - StudioDefaultsNotDefined + StudioDefaultsNotDefined, + SchemaError ) from pype.settings.lib import get_system_settings @@ -199,6 +202,7 @@ class SettingsCategoryWidget(QtWidgets.QWidget): save_btn.clicked.connect(self._save) + self.save_btn = save_btn self.scroll_widget = scroll_widget self.content_layout = content_layout self.content_widget = content_widget @@ -280,19 +284,49 @@ class SettingsCategoryWidget(QtWidgets.QWidget): self.content_layout.removeWidget(widget) widget.deleteLater() - self._create_root_entity() + dialog = None + try: + self._create_root_entity() - self.add_children_gui() + self.add_children_gui() - self.ignore_input_changes.set_ignore(True) + self.ignore_input_changes.set_ignore(True) - for input_field in self.input_fields: - input_field.set_entity_value() + for input_field in self.input_fields: + input_field.set_entity_value() - self.ignore_input_changes.set_ignore(False) + self.ignore_input_changes.set_ignore(False) + + except SchemaError as exc: + dialog = QtWidgets.QMessageBox(self) + dialog.setWindowTitle("Schema error") + msg = "Implementation bug!\n\nError: {}".format(str(exc)) + dialog.setText(msg) + dialog.setIcon(QtWidgets.QMessageBox.Warning) + + except Exception as exc: + formatted_traceback = traceback.format_exception(*sys.exc_info()) + dialog = QtWidgets.QMessageBox(self) + msg = "Unexpected error happened!\n\nError: {}".format(str(exc)) + dialog.setText(msg) + dialog.setDetailedText(formatted_traceback) + dialog.setIcon(QtWidgets.QMessageBox.Critical) self.set_state(CategoryState.Idle) + if dialog: + dialog.exec_() + self._on_reset_crash() + else: + self._on_reset_success() + + def _on_reset_crash(self): + self.save_btn.setEnabled(False) + + def _on_reset_success(self): + if not self.save_btn.isEnabled(): + self.save_btn.setEnabled(True) + def add_children_gui(self): for child_obj in self.entity.children: item = self.create_ui_for_entity(self, child_obj, self) @@ -404,6 +438,15 @@ class ProjectWidget(SettingsCategoryWidget): if self is saved_tab_widget: return + def _on_reset_crash(self): + self.project_list_widget.setEnabled(False) + super(ProjectWidget, self)._on_reset_crash() + + def _on_reset_success(self): + if not self.project_list_widget.isEnabled(): + self.project_list_widget.setEnabled(True) + super(ProjectWidget, self)._on_reset_success() + def _create_root_entity(self): self.entity = ProjectSettings(change_state=False) self.entity.on_change_callbacks.append(self._on_entity_change) From 26809bad907b3e76714fbc2fdb77ebe651ce630f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 16:22:19 +0100 Subject: [PATCH 098/295] fixed dialog arguments --- .../settings/settings/widgets/categories.py | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/pype/tools/settings/settings/widgets/categories.py b/pype/tools/settings/settings/widgets/categories.py index d84bf3dc15..263012fa52 100644 --- a/pype/tools/settings/settings/widgets/categories.py +++ b/pype/tools/settings/settings/widgets/categories.py @@ -309,9 +309,25 @@ class SettingsCategoryWidget(QtWidgets.QWidget): dialog = QtWidgets.QMessageBox(self) msg = "Unexpected error happened!\n\nError: {}".format(str(exc)) dialog.setText(msg) - dialog.setDetailedText(formatted_traceback) + dialog.setDetailedText("\n".join(formatted_traceback)) dialog.setIcon(QtWidgets.QMessageBox.Critical) + line_widths = set() + metricts = dialog.fontMetrics() + for line in formatted_traceback: + line_widths.add(metricts.width(line)) + max_width = max(line_widths) + + spacer = QtWidgets.QSpacerItem( + max_width, 0, + QtWidgets.QSizePolicy.Minimum, + QtWidgets.QSizePolicy.Expanding + ) + layout = dialog.layout() + layout.addItem( + spacer, layout.rowCount(), 0, 1, layout.columnCount() + ) + self.set_state(CategoryState.Idle) if dialog: @@ -345,8 +361,10 @@ class SettingsCategoryWidget(QtWidgets.QWidget): msg_box = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Warning, "Invalid input", - "There is invalid value in one of inputs." - " Please lead red color and fix them.", + ( + "There is invalid value in one of inputs." + " Please lead red color and fix them." + ), parent=self ) msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok) From 92591d45aa2e9e7770f4669b939ce0c54e5f9eb1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 16:22:58 +0100 Subject: [PATCH 099/295] plugin template also have 'active' key in --- .../projects_schema/schemas/template_publish_plugin.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json index 88151f7534..5151e4550d 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json @@ -21,10 +21,15 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "label", "label": "{docstring}" } ] } -] \ No newline at end of file +] From 722909b2db5c593a87a283f51146dfe17c5bb671 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 16:23:23 +0100 Subject: [PATCH 100/295] resaved defaults of optional plugins with active key --- .../defaults/project_settings/maya.json | 66 ++++++++++++------- .../defaults/project_settings/nuke.json | 12 ++-- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/pype/settings/defaults/project_settings/maya.json b/pype/settings/defaults/project_settings/maya.json index 8f991c7673..de8db5aa81 100644 --- a/pype/settings/defaults/project_settings/maya.json +++ b/pype/settings/defaults/project_settings/maya.json @@ -169,91 +169,113 @@ }, "ValidateColorSets": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshHasOverlappingUVs": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshArnoldAttributes": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshShaderConnections": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateMeshSingleUVSet": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshHasUVs": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateMeshLaminaFaces": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshNonManifold": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshNormalsUnlocked": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshUVSetMap1": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateMeshVerticesHaveEdges": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateNoAnimation": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateNoNamespace": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateNoNullTransforms": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateNoUnknownNodes": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateNodeNoGhosting": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateShapeDefaultNames": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateShapeRenderStats": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateTransformZero": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateCameraAttributes": { "enabled": false, - "optional": true + "optional": true, + "active": true }, "ValidateAssemblyName": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateAssRelativePaths": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ExtractPlayblast": { "capture_preset": { diff --git a/pype/settings/defaults/project_settings/nuke.json b/pype/settings/defaults/project_settings/nuke.json index d209a67106..f808f9caa5 100644 --- a/pype/settings/defaults/project_settings/nuke.json +++ b/pype/settings/defaults/project_settings/nuke.json @@ -30,19 +30,23 @@ }, "ValidateOutputResolution": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateGizmo": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateScript": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ValidateNukeWriteBoundingBox": { "enabled": true, - "optional": true + "optional": true, + "active": true }, "ExtractThumbnail": { "enabled": true, From 593de5e995700a22fe36d9ff9b1efdd8147ae189 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 24 Mar 2021 17:46:12 +0100 Subject: [PATCH 101/295] fix check of attribute values --- pype/settings/handlers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 1dae2526f5..6e93f2f405 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -386,13 +386,13 @@ class MongoSettingsHandler(SettingsHandler): @property def anatomy_keys(self): - if self._anatomy_keys: + if self._anatomy_keys is None: self._prepare_project_settings_keys() return self._anatomy_keys @property def attribute_keys(self): - if self._attribute_keys: + if self._attribute_keys is None: self._prepare_project_settings_keys() return self._attribute_keys From 694cc12caa2320d869a4c839889af5263ccccc7a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 24 Mar 2021 18:20:25 +0100 Subject: [PATCH 102/295] Delete test_localsystem.txt --- test_localsystem.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test_localsystem.txt diff --git a/test_localsystem.txt b/test_localsystem.txt deleted file mode 100644 index dde7986af8..0000000000 --- a/test_localsystem.txt +++ /dev/null @@ -1 +0,0 @@ -I have run From 93c771eaf0ec1f90eea72a14469b9e6a6e995a33 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 10:52:57 +0100 Subject: [PATCH 103/295] variant template expect 3 keys app_name app_variant and app_variant_label --- .../system_schema/host_settings/template_host_variant.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json index ba009cf094..c809891b30 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json @@ -7,8 +7,8 @@ }, { "type": "dict", - "key": "{host_name}_{host_version}", - "label": "{host_version}", + "key": "{app_name}_{app_variant}", + "label": "{app_variant_label}", "collapsible": true, "checkbox_key": "enabled", "children": [ @@ -78,7 +78,7 @@ "key": "environment", "label": "Environment", "type": "raw-json", - "env_group_key": "{host_name}_{host_version}" + "env_group_key": "{app_name}_{app_variant}" } ] } From 34b227612196f44e18f8536a2239e3eed4e891b0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 10:55:58 +0100 Subject: [PATCH 104/295] all aplications are passing new keys to variants --- .../host_settings/schema_aftereffects.json | 10 ++++---- .../host_settings/schema_blender.json | 10 ++++---- .../host_settings/schema_celaction.json | 10 ++++---- .../host_settings/schema_djv.json | 5 ++-- .../host_settings/schema_fusion.json | 10 ++++---- .../host_settings/schema_harmony.json | 10 ++++---- .../host_settings/schema_houdini.json | 10 ++++---- .../host_settings/schema_maya.json | 15 +++++++----- .../host_settings/schema_mayabatch.json | 15 +++++++----- .../host_settings/schema_photoshop.json | 10 ++++---- .../host_settings/schema_resolve.json | 5 ++-- .../host_settings/schema_shell.json | 15 +++++++----- .../host_settings/schema_tvpaint.json | 10 ++++---- .../host_settings/schema_unreal.json | 5 ++-- .../host_settings/template_nuke.json | 24 +++++++++---------- 15 files changed, 96 insertions(+), 68 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json index 4304c65445..6e1ba352fc 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "2020", - "host_name": "aftereffects" + "app_variant_label": "2020", + "app_variant": "2020", + "app_name": "aftereffects" }, { - "host_version": "2021", - "host_name": "aftereffects" + "app_variant_label": "2021", + "app_variant": "2021", + "app_name": "aftereffects" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json index 5d8cb45da8..725a0685b6 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "2.90", - "host_name": "blender" + "app_variant_label": "2.83", + "app_variant": "2_83", + "app_name": "blender" }, { - "host_version": "2.83", - "host_name": "blender" + "app_variant_label": "2.90", + "app_variant": "2_90", + "app_name": "blender" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json index ab3f0f3f15..6fa596808d 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json @@ -29,14 +29,16 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "Local", - "host_name": "celation", + "app_variant_label": "Local", + "app_variant": "Local", + "app_name": "celation", "multiplatform": false, "multipath_executables": false }, { - "host_version": "Publish", - "host_name": "celation", + "app_variant_label": "Publish", + "app_variant": "Publish", + "app_name": "celation", "multiplatform": false, "multipath_executables": false } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json index 02c90a92ad..8bbdb7ea9b 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json @@ -28,8 +28,9 @@ "type": "schema_template", "name": "template_host_variant", "template_data": { - "host_version": "1.1", - "host_name": "djvview" + "app_variant_label": "1.1", + "app_variant": "1_1", + "app_name": "djvview" } } ] diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index 1c1b7653d9..d693c39ffe 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "16", - "host_name": "fusion" + "app_variant_label": "16", + "app_variant": "16", + "app_name": "fusion" }, { - "host_version": "9", - "host_name": "fusion" + "app_variant_label": "9", + "app_variant": "9", + "app_name": "fusion" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json index b0abf35bfa..8ad07c95ba 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "20", - "host_name": "harmony" + "app_variant_label": "20", + "app_variant": "20", + "app_name": "harmony" }, { - "host_version": "17", - "host_name": "harmony" + "app_variant_label": "17", + "app_variant": "17", + "app_name": "harmony" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json index cc0cd54cf2..399261528b 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "18", - "host_name": "houdini" + "app_variant_label": "18", + "app_variant": "18", + "app_name": "houdini" }, { - "host_version": "17", - "host_name": "houdini" + "app_variant_label": "17", + "app_variant": "17", + "app_name": "houdini" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json index 84782cb3d8..d8396b16cb 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json @@ -29,16 +29,19 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "2020", - "host_name": "maya" + "app_variant_label": "2020", + "app_variant": "2020", + "app_name": "maya" }, { - "host_version": "2019", - "host_name": "maya" + "app_variant_label": "2019", + "app_variant": "2019", + "app_name": "maya" }, { - "host_version": "2018", - "host_name": "maya" + "app_variant_label": "2018", + "app_variant": "2018", + "app_name": "maya" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json index dbd850dcd6..af7cc3d301 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json @@ -29,16 +29,19 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "2020", - "host_name": "mayabatch" + "app_variant_label": "2020", + "app_variant": "2020", + "app_name": "mayabatch" }, { - "host_version": "2019", - "host_name": "mayabatch" + "app_variant_label": "2019", + "app_variant": "2019", + "app_name": "mayabatch" }, { - "host_version": "2018", - "host_name": "mayabatch" + "app_variant_label": "2018", + "app_variant": "2018", + "app_name": "mayabatch" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json index 136eb16888..a8e3574aa3 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "2020", - "host_name": "photoshop" + "app_variant_label": "2020", + "app_variant": "2020", + "app_name": "photoshop" }, { - "host_version": "2021", - "host_name": "photoshop" + "app_variant_label": "2021", + "app_variant": "2021", + "app_name": "photoshop" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json index 2d11e1def4..052a935410 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json @@ -29,8 +29,9 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "16", - "host_name": "resolve" + "app_variant_label": "16", + "app_variant": "16", + "app_name": "resolve" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json index 4fdbd65c24..f72450aa08 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json @@ -25,16 +25,19 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "Python 3.7", - "host_name": "python" + "app_variant": "python_3_7", + "app_variant_label": "Python 3.7", + "app_name": "python" }, { - "host_version": "Python 2.7", - "host_name": "python" + "app_variant": "python_2_7", + "app_variant_label": "Python 2.7", + "app_name": "python" }, { - "host_version": "Terminal", - "host_name": "terminal" + "app_variant": "terminal", + "app_variant_label": "Terminal", + "app_name": "terminal" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json index 1c88d12cab..a569ec0503 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json @@ -29,12 +29,14 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "Animation 11 (64bits)", - "host_name": "tvpaint" + "app_variant_label": "Animation 11 (64bits)", + "app_variant": "animation_11_64bit", + "app_name": "tvpaint" }, { - "host_version": "Animation 11 (32bits)", - "host_name": "tvpaint" + "app_variant_label": "Animation 11 (32bits)", + "app_variant": "animation_11_32bit", + "app_name": "tvpaint" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json index d7065ad3ff..b23a21b0fd 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json @@ -29,8 +29,9 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "4.24", - "host_name": "unreal" + "app_variant": "4_24", + "app_variant_label": "4.24", + "app_name": "unreal" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json index 01c3be726a..d32f87949d 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json @@ -30,24 +30,24 @@ "name": "template_host_variant", "template_data": [ { - "host_version": "12.2", - "host_name": "{nuke_type}", - "multipath_executables": true + "app_variant": "12_2", + "app_variant_label": "12.2", + "app_name": "{nuke_type}" }, { - "host_version": "12.0", - "host_name": "{nuke_type}", - "multipath_executables": true + "app_variant": "12_0", + "app_variant_label": "12.0", + "app_name": "{nuke_type}" }, { - "host_version": "11.3", - "host_name": "{nuke_type}", - "multipath_executables": true + "app_variant": "11_3", + "app_variant_label": "11.3", + "app_name": "{nuke_type}" }, { - "host_version": "11.2", - "host_name": "{nuke_type}", - "multipath_executables": true + "app_variant": "11_2", + "app_variant_label": "11.2", + "app_name": "{nuke_type}" } ] } From 6b2ababb62f71a59532aea29f756562775ac97d8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 10:56:13 +0100 Subject: [PATCH 105/295] resaved keys in defaults --- .../system_settings/applications.json | 156 +++++++++--------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index 4a13cf78f6..436ef62342 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -253,7 +253,7 @@ } }, "variants": { - "nuke_12.2": { + "nuke_12_2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -274,11 +274,11 @@ }, "environment": { "__environment_keys__": { - "nuke_12.2": [] + "nuke_12_2": [] } } }, - "nuke_12.0": { + "nuke_12_0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -299,11 +299,11 @@ }, "environment": { "__environment_keys__": { - "nuke_12.0": [] + "nuke_12_0": [] } } }, - "nuke_11.3": { + "nuke_11_3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -324,11 +324,11 @@ }, "environment": { "__environment_keys__": { - "nuke_11.3": [] + "nuke_11_3": [] } } }, - "nuke_11.2": { + "nuke_11_2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -347,7 +347,7 @@ }, "environment": { "__environment_keys__": { - "nuke_11.2": [] + "nuke_11_2": [] } } } @@ -377,7 +377,7 @@ } }, "variants": { - "nukex_12.2": { + "nukex_12_2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -404,11 +404,11 @@ }, "environment": { "__environment_keys__": { - "nukex_12.2": [] + "nukex_12_2": [] } } }, - "nukex_12.0": { + "nukex_12_0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -435,11 +435,11 @@ }, "environment": { "__environment_keys__": { - "nukex_12.0": [] + "nukex_12_0": [] } } }, - "nukex_11.3": { + "nukex_11_3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -466,11 +466,11 @@ }, "environment": { "__environment_keys__": { - "nukex_11.3": [] + "nukex_11_3": [] } } }, - "nukex_11.2": { + "nukex_11_2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -495,7 +495,7 @@ }, "environment": { "__environment_keys__": { - "nukex_11.2": [] + "nukex_11_2": [] } } } @@ -527,7 +527,7 @@ } }, "variants": { - "nukestudio_12.2": { + "nukestudio_12_2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -554,11 +554,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_12.2": [] + "nukestudio_12_2": [] } } }, - "nukestudio_12.0": { + "nukestudio_12_0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -585,11 +585,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_12.0": [] + "nukestudio_12_0": [] } } }, - "nukestudio_11.3": { + "nukestudio_11_3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -616,11 +616,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_11.3": [] + "nukestudio_11_3": [] } } }, - "nukestudio_11.2": { + "nukestudio_11_2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -643,7 +643,7 @@ }, "environment": { "__environment_keys__": { - "nukestudio_11.2": [] + "nukestudio_11_2": [] } } } @@ -675,7 +675,7 @@ } }, "variants": { - "hiero_12.2": { + "hiero_12_2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -702,11 +702,11 @@ }, "environment": { "__environment_keys__": { - "hiero_12.2": [] + "hiero_12_2": [] } } }, - "hiero_12.0": { + "hiero_12_0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -733,11 +733,11 @@ }, "environment": { "__environment_keys__": { - "hiero_12.0": [] + "hiero_12_0": [] } } }, - "hiero_11.3": { + "hiero_11_3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -764,11 +764,11 @@ }, "environment": { "__environment_keys__": { - "hiero_11.3": [] + "hiero_11_3": [] } } }, - "hiero_11.2": { + "hiero_11_2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -793,7 +793,7 @@ }, "environment": { "__environment_keys__": { - "hiero_11.2": [] + "hiero_11_2": [] } } } @@ -1057,36 +1057,7 @@ } }, "variants": { - "blender_2.90": { - "enabled": true, - "label": "", - "variant_label": "2.90", - "icon": "", - "executables": { - "windows": [ - "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [ - "--python-use-system-env" - ], - "darwin": [ - "--python-use-system-env" - ], - "linux": [ - "--python-use-system-env" - ] - }, - "environment": { - "__environment_keys__": { - "blender_2.90": [] - } - } - }, - "blender_2.83": { + "blender_2_83": { "enabled": true, "label": "", "variant_label": "2.83", @@ -1111,7 +1082,36 @@ }, "environment": { "__environment_keys__": { - "blender_2.83": [] + "blender_2_83": [] + } + } + }, + "blender_2_90": { + "enabled": true, + "label": "", + "variant_label": "2.90", + "icon": "", + "executables": { + "windows": [ + "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" + ], + "darwin": [], + "linux": [] + }, + "arguments": { + "windows": [ + "--python-use-system-env" + ], + "darwin": [ + "--python-use-system-env" + ], + "linux": [ + "--python-use-system-env" + ] + }, + "environment": { + "__environment_keys__": { + "blender_2_90": [] } } } @@ -1193,7 +1193,7 @@ } }, "variants": { - "tvpaint_Animation 11 (64bits)": { + "tvpaint_animation_11_64bit": { "enabled": true, "label": "", "variant_label": "11 (64bits)", @@ -1212,11 +1212,11 @@ }, "environment": { "__environment_keys__": { - "tvpaint_Animation 11 (64bits)": [] + "tvpaint_animation_11_64bit": [] } } }, - "tvpaint_Animation 11 (32bits)": { + "tvpaint_animation_11_32bit": { "enabled": true, "label": "", "variant_label": "11 (32bits)", @@ -1235,7 +1235,7 @@ }, "environment": { "__environment_keys__": { - "tvpaint_Animation 11 (32bits)": [] + "tvpaint_animation_11_32bit": [] } } } @@ -1445,7 +1445,7 @@ } }, "variants": { - "unreal_4.24": { + "unreal_4_24": { "enabled": true, "label": "", "variant_label": "4.24", @@ -1462,7 +1462,7 @@ }, "environment": { "__environment_keys__": { - "unreal_4.24": [] + "unreal_4_24": [] } } } @@ -1476,7 +1476,7 @@ } }, "variants": { - "python_Python 3.7": { + "python_python_3_7": { "enabled": true, "label": "Python", "variant_label": "3.7", @@ -1493,11 +1493,11 @@ }, "environment": { "__environment_keys__": { - "python_Python 3.7": [] + "python_python_3_7": [] } } }, - "python_Python 2.7": { + "python_python_2_7": { "enabled": true, "label": "Python", "variant_label": "2.7", @@ -1514,11 +1514,11 @@ }, "environment": { "__environment_keys__": { - "python_Python 2.7": [] + "python_python_2_7": [] } } }, - "terminal_Terminal": { + "terminal_terminal": { "enabled": true, "label": "Terminal", "variant_label": "", @@ -1535,7 +1535,7 @@ }, "environment": { "__environment_keys__": { - "terminal_Terminal": [] + "terminal_terminal": [] } } } @@ -1552,7 +1552,7 @@ } }, "variants": { - "djvview_1.1": { + "djvview_1_1": { "enabled": true, "label": "", "variant_label": "1.1", @@ -1569,10 +1569,10 @@ }, "environment": { "__environment_keys__": { - "djvview_1.1": [] + "djvview_1_1": [] } } } } } -} +} \ No newline at end of file From 80abe4b9aaf74f8cb85c20a4f31502944504d324 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 11:08:17 +0100 Subject: [PATCH 106/295] added active key t oremaining optional plugins --- .../schema_project_deadline.json | 20 +++++++++++++++++++ .../schemas/schema_maya_publish.json | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 97b2805959..2070e4c8f5 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -29,6 +29,11 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "enum", "key": "tile_assembler_plugin", @@ -83,6 +88,11 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "boolean", "key": "use_published", @@ -137,6 +147,11 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "boolean", "key": "use_published", @@ -191,6 +206,11 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "boolean", "key": "use_published", diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index 623658b7a2..9d2e39edde 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -271,6 +271,11 @@ "key": "optional", "label": "Optional" }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, { "type": "raw-json", "key": "bake_attributes", From 28f85892f8822f03f7550d02f70872b09cc698cb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 11:08:25 +0100 Subject: [PATCH 107/295] saved default values --- pype/settings/defaults/project_settings/deadline.json | 4 ++++ pype/settings/defaults/project_settings/maya.json | 1 + 2 files changed, 5 insertions(+) diff --git a/pype/settings/defaults/project_settings/deadline.json b/pype/settings/defaults/project_settings/deadline.json index 892fb5d29f..6d36f38423 100644 --- a/pype/settings/defaults/project_settings/deadline.json +++ b/pype/settings/defaults/project_settings/deadline.json @@ -3,6 +3,7 @@ "MayaSubmitDeadline": { "enabled": true, "optional": false, + "active": true, "tile_assembler_plugin": "oiio", "use_published": true, "asset_dependencies": true, @@ -12,6 +13,7 @@ "NukeSubmitDeadline": { "enabled": true, "optional": false, + "active": true, "use_published": true, "priority": 50, "chunk_size": 10, @@ -23,6 +25,7 @@ "HarmonySubmitDeadline": { "enabled": true, "optional": false, + "active": true, "use_published": true, "priority": 50, "chunk_size": 10000, @@ -34,6 +37,7 @@ "AfterEffectsSubmitDeadline": { "enabled": true, "optional": false, + "active": true, "use_published": true, "priority": 50, "chunk_size": 10000, diff --git a/pype/settings/defaults/project_settings/maya.json b/pype/settings/defaults/project_settings/maya.json index de8db5aa81..6945bb0581 100644 --- a/pype/settings/defaults/project_settings/maya.json +++ b/pype/settings/defaults/project_settings/maya.json @@ -379,6 +379,7 @@ "ExtractCameraAlembic": { "enabled": true, "optional": true, + "active": true, "bake_attributes": [] }, "MayaSubmitDeadline": { From d55d133b7987aee1963fafb47df65e8d38b16e46 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:06:42 +0100 Subject: [PATCH 108/295] replaced dots in default tools --- pype/settings/defaults/system_settings/tools.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/settings/defaults/system_settings/tools.json b/pype/settings/defaults/system_settings/tools.json index af5772705c..fce847fb55 100644 --- a/pype/settings/defaults/system_settings/tools.json +++ b/pype/settings/defaults/system_settings/tools.json @@ -36,18 +36,18 @@ } }, "variants": { - "mtoa_3.2": { + "mtoa_3_2": { "MTOA_VERSION": "3.2", "__environment_keys__": { - "mtoa_3.2": [ + "mtoa_3_2": [ "MTOA_VERSION" ] } }, - "mtoa_3.1": { + "mtoa_3_1": { "MTOA_VERSION": "3.1", "__environment_keys__": { - "mtoa_3.1": [ + "mtoa_3_1": [ "MTOA_VERSION" ] } From 1ba1cf9acace5200f6d95fd4be37380cb8177121 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:27:30 +0100 Subject: [PATCH 109/295] nuke shortcuts have valid keys --- pype/settings/defaults/project_settings/nuke.json | 10 +++++----- .../schemas/projects_schema/schema_project_nuke.json | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pype/settings/defaults/project_settings/nuke.json b/pype/settings/defaults/project_settings/nuke.json index f808f9caa5..d727a6ba1e 100644 --- a/pype/settings/defaults/project_settings/nuke.json +++ b/pype/settings/defaults/project_settings/nuke.json @@ -1,11 +1,11 @@ { "menu": { "Pype": { - "Create...": "ctrl+shift+alt+c", - "Publish...": "ctrl+alt+p", - "Load...": "ctrl+alt+l", - "Manage...": "ctrl+alt+m", - "Build Workfile": "ctrl+alt+b" + "create": "ctrl+shift+alt+c", + "publish": "ctrl+alt+p", + "load": "ctrl+alt+l", + "manage": "ctrl+alt+m", + "build_workfile": "ctrl+alt+b" } }, "create": { diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json index 90e068ba33..3fe01cad09 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -20,27 +20,27 @@ "children": [ { "type": "text", - "key": "Create...", + "key": "create", "label": "Create..." }, { "type": "text", - "key": "Publish...", + "key": "publish", "label": "Publish..." }, { "type": "text", - "key": "Load...", + "key": "load", "label": "Load..." }, { "type": "text", - "key": "Manage...", + "key": "manage", "label": "Manage..." }, { "type": "text", - "key": "Build Workfile", + "key": "build_workfile", "label": "Build Workfile" } ] From 220454aa542a9006e60f48be4e8f9ddf2bea7d53 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:27:54 +0100 Subject: [PATCH 110/295] added key -> label mapping to nuke shortcut implementation --- pype/hosts/nuke/api/menu.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index 9ff1dc251a..3f97cc228a 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -85,6 +85,13 @@ def add_shortcuts_from_presets(): nuke_presets = get_current_project_settings()["nuke"] if nuke_presets.get("menu"): + menu_label_mapping = { + "manage": "Manage...", + "create": "Create...", + "load": "Load...", + "build_workfile": "Build Workfile", + "publish": "Publish..." + } for menu_name, menuitems in nuke_presets.get("menu").items(): menu = menubar.findItem(menu_name) for mitem_name, shortcut in menuitems.items(): @@ -92,7 +99,8 @@ def add_shortcuts_from_presets(): shortcut, mitem_name )) try: - menuitem = menu.findItem(mitem_name) + item_label = menu_label_mapping[mitem_name] + menuitem = menu.findItem(item_label) menuitem.setShortcut(shortcut) except AttributeError as e: log.error(e) From 96a80438e08115f6a8cc7ca5e57c5b7f97912a11 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:28:28 +0100 Subject: [PATCH 111/295] defined allowed key symbols and regex in constants --- pype/settings/constants.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pype/settings/constants.py b/pype/settings/constants.py index ce19ad3f93..f6077e826e 100644 --- a/pype/settings/constants.py +++ b/pype/settings/constants.py @@ -1,3 +1,6 @@ +import re + + # Metadata keys for work with studio and project overrides M_OVERRIDEN_KEY = "__overriden_keys__" # Metadata key for storing information about environments @@ -19,6 +22,10 @@ LOCAL_SETTING_KEY = "local_settings" DEFAULT_PROJECT_KEY = "__default_project__" +KEY_ALLOWED_SYMBOLS = "a-zA-Z0-9-_ " +KEY_REGEX = re.compile(r"^[{}]+$".format(KEY_ALLOWED_SYMBOLS)) + + __all__ = ( "M_OVERRIDEN_KEY", "M_ENVIRONMENT_KEY", @@ -29,5 +36,10 @@ __all__ = ( "SYSTEM_SETTINGS_KEY", "PROJECT_SETTINGS_KEY", "PROJECT_ANATOMY_KEY", - "LOCAL_SETTING_KEY" + "LOCAL_SETTING_KEY", + + "DEFAULT_PROJECT_KEY", + + "KEY_ALLOWED_SYMBOLS", + "KEY_REGEX" ) From 7f39cf5dd492e0c6c5ea583343ee1c4a7cf65f09 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:28:48 +0100 Subject: [PATCH 112/295] implemented exception InvalidKeySymbols --- pype/settings/entities/exceptions.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pype/settings/entities/exceptions.py b/pype/settings/entities/exceptions.py index 2c3b262ff1..f86d08ab5f 100644 --- a/pype/settings/entities/exceptions.py +++ b/pype/settings/entities/exceptions.py @@ -1,3 +1,6 @@ +from pype.settings.constants import KEY_ALLOWED_SYMBOLS + + class DefaultsNotDefined(Exception): def __init__(self, obj): msg = "Default values for object are not set. {}".format(obj.path) @@ -34,6 +37,14 @@ class RequiredKeyModified(KeyError): super(RequiredKeyModified, self).__init__(msg.format(entity_path, key)) +class InvalidKeySymbols(KeyError): + def __init__(self, entity_path, key): + msg = "{} - Invalid key \"{}\". Allowed symbols are {}" + super(InvalidKeySymbols, self).__init__( + msg.format(entity_path, key, KEY_ALLOWED_SYMBOLS) + ) + + class SchemaError(Exception): pass From 01d066025380e7eeb112fa31fa4e799af0cfe4a5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:29:12 +0100 Subject: [PATCH 113/295] immutable dict is validating keys with allowed symbols --- pype/settings/entities/dict_immutable_keys_entity.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/dict_immutable_keys_entity.py b/pype/settings/entities/dict_immutable_keys_entity.py index 92a36b7dca..270e635736 100644 --- a/pype/settings/entities/dict_immutable_keys_entity.py +++ b/pype/settings/entities/dict_immutable_keys_entity.py @@ -7,7 +7,8 @@ from .lib import ( ) from pype.settings.constants import ( METADATA_KEYS, - M_OVERRIDEN_KEY + M_OVERRIDEN_KEY, + KEY_REGEX ) from . import ( BaseItemEntity, @@ -17,7 +18,8 @@ from . import ( ) from .exceptions import ( SchemaDuplicatedKeys, - EntitySchemaError + EntitySchemaError, + InvalidKeySymbols ) @@ -88,6 +90,10 @@ class DictImmutableKeysEntity(ItemEntity): else: raise SchemaDuplicatedKeys(self, child_entity.key) + for key in self.keys(): + if not KEY_REGEX.match(key): + raise InvalidKeySymbols(self.path, key) + if self.checkbox_key: checkbox_child = self.non_gui_children.get(self.checkbox_key) if not checkbox_child: From 48a300cfc312bc228172b0ab7f5a55cd54f202ca Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:29:56 +0100 Subject: [PATCH 114/295] mutable dictionary validate keys on change and tries to fix them on load --- pype/settings/entities/__init__.py | 2 ++ .../entities/dict_mutable_keys_entity.py | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/__init__.py b/pype/settings/entities/__init__.py index 1cb4be62e7..2ff911e7d4 100644 --- a/pype/settings/entities/__init__.py +++ b/pype/settings/entities/__init__.py @@ -58,6 +58,7 @@ from .exceptions import ( DefaultsNotDefined, StudioDefaultsNotDefined, InvalidValueType, + InvalidKeySymbols, SchemaMissingFileInfo, SchemeGroupHierarchyBug, SchemaDuplicatedKeys, @@ -114,6 +115,7 @@ __all__ = ( "DefaultsNotDefined", "StudioDefaultsNotDefined", "InvalidValueType", + "InvalidKeySymbols", "SchemaMissingFileInfo", "SchemeGroupHierarchyBug", "SchemaDuplicatedKeys", diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index 7005d346c1..12a18ad612 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -1,3 +1,4 @@ +import re import copy from .lib import ( @@ -7,6 +8,7 @@ from .lib import ( from . import EndpointEntity from .exceptions import ( DefaultsNotDefined, + InvalidKeySymbols, StudioDefaultsNotDefined, RequiredKeyModified, EntitySchemaError @@ -14,7 +16,9 @@ from .exceptions import ( from pype.settings.constants import ( METADATA_KEYS, M_DYNAMIC_KEY_LABEL, - M_ENVIRONMENT_KEY + M_ENVIRONMENT_KEY, + KEY_REGEX, + KEY_ALLOWED_SYMBOLS ) @@ -92,6 +96,9 @@ class DictMutableKeysEntity(EndpointEntity): # TODO Check for value type if is Settings entity? child_obj = self.children_by_key.get(key) if not child_obj: + if not KEY_REGEX.match(key): + raise InvalidKeySymbols(self.path, key) + child_obj = self.add_key(key) child_obj.set(value) @@ -102,6 +109,10 @@ class DictMutableKeysEntity(EndpointEntity): if new_key == old_key: return + + if not KEY_REGEX.match(new_key): + raise InvalidKeySymbols(self.path, new_key) + self.children_by_key[new_key] = self.children_by_key.pop(old_key) self._on_key_label_change() @@ -116,6 +127,9 @@ class DictMutableKeysEntity(EndpointEntity): if key in self.children_by_key: self.pop(key) + if not KEY_REGEX.match(key): + raise InvalidKeySymbols(self.path, key) + if self.value_is_env_group: item_schema = copy.deepcopy(self.item_schema) item_schema["env_group_key"] = key @@ -325,6 +339,15 @@ class DictMutableKeysEntity(EndpointEntity): children_label_by_id = {} metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {} for _key, _value in new_value.items(): + if not KEY_REGEX.match(_key): + # Replace invalid characters with underscore + # - this is safety to not break already existing settings + _key = re.sub( + r"[^{}]+".format(KEY_ALLOWED_SYMBOLS), + "_", + _key + ) + child_entity = self._add_key(_key) child_entity.update_default_value(_value) if using_project_overrides: From f5e9096fdcfd142f447de6ea4563efe4d2054fa2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:38:42 +0100 Subject: [PATCH 115/295] added key validation to roots entity --- pype/settings/entities/root_entities.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index 82885e8479..2d33689697 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -13,11 +13,15 @@ from .lib import ( get_studio_settings_schema, get_project_settings_schema ) -from .exceptions import EntitySchemaError +from .exceptions import ( + EntitySchemaError, + InvalidKeySymbols +) from pype.settings.constants import ( SYSTEM_SETTINGS_KEY, PROJECT_SETTINGS_KEY, - PROJECT_ANATOMY_KEY + PROJECT_ANATOMY_KEY, + KEY_REGEX ) from pype.settings.lib import ( @@ -153,6 +157,10 @@ class RootEntity(BaseItemEntity): raise EntitySchemaError(self, reason) child_entity.schema_validations() + for key in self.non_gui_children.keys(): + if not KEY_REGEX.match(key): + raise InvalidKeySymbols(self.path, key) + def get_entity_from_path(self, path): """Return system settings entity.""" raise NotImplementedError(( From 2567fee07284019d3445295ad2ae5e34b358343a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 13:52:15 +0100 Subject: [PATCH 116/295] added key validations to modifiable dict widget --- .../settings/widgets/dict_mutable_widget.py | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/dict_mutable_widget.py b/pype/tools/settings/settings/widgets/dict_mutable_widget.py index 0cb051082e..c55af7a774 100644 --- a/pype/tools/settings/settings/widgets/dict_mutable_widget.py +++ b/pype/tools/settings/settings/widgets/dict_mutable_widget.py @@ -12,6 +12,7 @@ from .lib import ( BTN_FIXED_SIZE, CHILD_OFFSET ) +from pype.settings.constants import KEY_REGEX def create_add_btn(parent): @@ -37,6 +38,7 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget): self.collapsible_key = entity_widget.entity.collapsible_key self.is_duplicated = False + self.key_is_valid = False if self.collapsible_key: self.create_collapsible_ui() @@ -86,6 +88,9 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget): if self.is_duplicated: return + if not self.key_is_valid: + return + key = self.key_input.text() if key: label = self.key_label_input.text() @@ -95,9 +100,10 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget): def _on_key_change(self): key = self.key_input.text() + self.key_is_valid = KEY_REGEX.match(key) self.is_duplicated = self.entity_widget.is_key_duplicated(key) key_input_state = "" - if self.is_duplicated: + if self.is_duplicated or not self.key_is_valid: key_input_state = "invalid" elif key != "": key_input_state = "modified" @@ -157,6 +163,7 @@ class ModifiableDictItem(QtWidgets.QWidget): self.ignore_input_changes = entity_widget.ignore_input_changes self.is_key_duplicated = False + self.key_is_valid = False self.is_required = False self.origin_key = None @@ -382,6 +389,11 @@ class ModifiableDictItem(QtWidgets.QWidget): def _on_key_change(self): key = self.key_value() + self.key_is_valid = KEY_REGEX.match(key) + if not self.key_is_valid: + self.update_style() + return + is_key_duplicated = self.entity_widget.validate_key_duplication( self.temp_key, key, self ) @@ -458,6 +470,7 @@ class ModifiableDictItem(QtWidgets.QWidget): self.is_key_duplicated or self.key_value() == "" or self.child_invalid + or not self.key_is_valid ) @property @@ -473,7 +486,11 @@ class ModifiableDictItem(QtWidgets.QWidget): def update_style(self): key_input_state = "" - if self.is_key_duplicated or self.key_value() == "": + if ( + self.is_key_duplicated + or self.key_value() == "" + or not self.key_is_valid + ): key_input_state = "invalid" elif self.is_key_modified(): key_input_state = "modified" From 994238a63812031655deb51020dc319016b3398f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:11:03 +0100 Subject: [PATCH 117/295] better key validation --- .../settings/settings/widgets/dict_mutable_widget.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/widgets/dict_mutable_widget.py b/pype/tools/settings/settings/widgets/dict_mutable_widget.py index c55af7a774..e704dd40ee 100644 --- a/pype/tools/settings/settings/widgets/dict_mutable_widget.py +++ b/pype/tools/settings/settings/widgets/dict_mutable_widget.py @@ -341,7 +341,7 @@ class ModifiableDictItem(QtWidgets.QWidget): else: self._on_focus_lose() - if not self.is_key_duplicated: + if not self.is_key_duplicated and self.key_is_valid: self.entity_widget.change_key(self.key_value(), self) def set_key_label(self, key, label): @@ -390,15 +390,11 @@ class ModifiableDictItem(QtWidgets.QWidget): def _on_key_change(self): key = self.key_value() self.key_is_valid = KEY_REGEX.match(key) - if not self.key_is_valid: - self.update_style() - return - is_key_duplicated = self.entity_widget.validate_key_duplication( self.temp_key, key, self ) self.temp_key = key - if is_key_duplicated: + if is_key_duplicated or not self.key_is_valid: return if key: From 9a0070e5a123def51d3b0a079587b737a5cd1a71 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:20:29 +0100 Subject: [PATCH 118/295] fixed modifiable dict collapsible key widget --- pype/tools/settings/settings/widgets/dict_mutable_widget.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/dict_mutable_widget.py b/pype/tools/settings/settings/widgets/dict_mutable_widget.py index e704dd40ee..e44ffdf35a 100644 --- a/pype/tools/settings/settings/widgets/dict_mutable_widget.py +++ b/pype/tools/settings/settings/widgets/dict_mutable_widget.py @@ -765,15 +765,17 @@ class DictMutableKeysWidget(BaseWidget): old_key_items.append(input_field) if duplicated_items: - widget.set_is_key_duplicated(True) for input_field in duplicated_items: input_field.set_is_key_duplicated(True) + widget.set_is_key_duplicated(True) else: widget.set_is_key_duplicated(False) if len(old_key_items) == 1: for input_field in old_key_items: input_field.set_is_key_duplicated(False) + input_field.set_key(old_key) + input_field.update_key_label() self.trigger_hierarchical_style_update() return bool(duplicated_items) From 73df4150a7df87c63fb6b26a0e094f3779988cdb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:33:52 +0100 Subject: [PATCH 119/295] extract review use None as value of width and height --- pype/plugins/publish/extract_review.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/plugins/publish/extract_review.py b/pype/plugins/publish/extract_review.py index 5414ae5289..f6530219a6 100644 --- a/pype/plugins/publish/extract_review.py +++ b/pype/plugins/publish/extract_review.py @@ -757,8 +757,9 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.debug("input_height: `{}`".format(input_height)) # NOTE Setting only one of `width` or `heigth` is not allowed - output_width = output_def.get("width") - output_height = output_def.get("height") + # - settings value can't have None but has value of 0 + output_width = output_def.get("width") or None + output_height = output_def.get("height") or None # Use instance resolution if output definition has not set it. if output_width is None or output_height is None: output_width = temp_data["resolution_width"] From af300ff0af11b794d0a0a17a03f7bd138b653be8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:35:48 +0100 Subject: [PATCH 120/295] added width and height items to extract review output definitions --- .../schemas/schema_global_publish.json | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index f97bfb11b3..b4d1876297 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -177,6 +177,29 @@ "object_type": "text" } ] + }, + { + "type": "separator" + }, + { + "type": "label", + "label": "Width and Height must be both set to higher value than 0 else source resolution is used." + }, + { + "key": "width", + "label": "Output width", + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 100000 + }, + { + "key": "height", + "label": "Output height", + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 100000 } ] } From 6be4414a13c60282032fe9a672d6fd790f13c8ee Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:36:19 +0100 Subject: [PATCH 121/295] number entity can expect default value --- pype/settings/entities/input_entities.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/input_entities.py b/pype/settings/entities/input_entities.py index 921171cfff..f668cfde2d 100644 --- a/pype/settings/entities/input_entities.py +++ b/pype/settings/entities/input_entities.py @@ -329,12 +329,15 @@ class NumberEntity(InputEntity): self.maximum = self.schema_data.get("maximum", 99999) self.decimal = self.schema_data.get("decimal", 0) + value_on_not_set = self.schema_data.get("default", 0) if self.decimal: valid_value_types = (float, ) + value_on_not_set = float(value_on_not_set) else: valid_value_types = (int, ) + value_on_not_set = int(value_on_not_set) self.valid_value_types = valid_value_types - self.value_on_not_set = 0 + self.value_on_not_set = value_on_not_set def _convert_to_valid_type(self, value): if isinstance(value, str): From ea6f21ee808f756f42e4c0870071b00a8029c346 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 14:36:49 +0100 Subject: [PATCH 122/295] resaved defaults of extract review plugin --- pype/settings/defaults/project_settings/global.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index 63c092ec27..794700bc2b 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -41,7 +41,9 @@ "review", "ftrack" ] - } + }, + "width": 0, + "height": 0 } } } From 712670ec60c661c347049ef52174001787e479ce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 15:37:57 +0100 Subject: [PATCH 123/295] moved project plugin paths to project settings --- .../schemas/projects_schema/schema_project_global.json | 8 ++++++++ .../entities/schemas/system_schema/schema_general.json | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_global.json b/pype/settings/entities/schemas/projects_schema/schema_project_global.json index 1733e04f67..ebc8d08fb8 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_global.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_global.json @@ -22,6 +22,14 @@ { "type": "schema", "name": "schema_project_syncserver" + }, + { + "key": "project_plugins", + "type": "path", + "label": "Additional Project Plugin Paths", + "multiplatform": true, + "multipath": true, + "use_label_wrap": true } ] } diff --git a/pype/settings/entities/schemas/system_schema/schema_general.json b/pype/settings/entities/schemas/system_schema/schema_general.json index b029081c7c..cf88043cd0 100644 --- a/pype/settings/entities/schemas/system_schema/schema_general.json +++ b/pype/settings/entities/schemas/system_schema/schema_general.json @@ -18,13 +18,6 @@ { "type": "splitter" }, - { - "key": "project_plugins", - "type": "path", - "label": "Additional Project Plugins Path", - "multiplatform": true, - "multipath": false - }, { "key": "studio_soft", "type": "path", From bba39ff457bd43e95663574c287d7ae6211ccc66 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 15:38:17 +0100 Subject: [PATCH 124/295] save defaults of project plugins --- pype/settings/defaults/project_settings/global.json | 5 +++++ pype/settings/defaults/system_settings/general.json | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index 63c092ec27..e252a103ac 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -1,4 +1,9 @@ { + "project_plugins": { + "windows": [], + "darwin": [], + "linux": [] + }, "publish": { "IntegrateHeroVersion": { "enabled": true diff --git a/pype/settings/defaults/system_settings/general.json b/pype/settings/defaults/system_settings/general.json index bf2bb5def0..e03e00aca8 100644 --- a/pype/settings/defaults/system_settings/general.json +++ b/pype/settings/defaults/system_settings/general.json @@ -1,11 +1,6 @@ { "studio_name": "Studio name", "studio_code": "stu", - "project_plugins": { - "windows": "convert from \"PYPE_PROJECT_PLUGINS\"", - "darwin": "", - "linux": "" - }, "studio_soft": { "windows": "convert from \"STUDIO_SOFT\"", "darwin": "", From 2b4890e6594025bfd5d2ccd3bb0a3bf0f19922df Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:05:52 +0100 Subject: [PATCH 125/295] removed usage of PYPE_PROJECT_PLUGINS --- pype/__init__.py | 13 ------------- pype/hosts/celaction/api/cli.py | 8 -------- pype/tools/standalonepublish/publish.py | 8 -------- 3 files changed, 29 deletions(-) diff --git a/pype/__init__.py b/pype/__init__.py index fd0ba321ed..0add849457 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -99,20 +99,7 @@ def install(): pyblish.register_discovery_filter(filter_pyblish_plugins) avalon.register_plugin_path(avalon.Loader, LOAD_PATH) - # Register project specific plugins project_name = os.environ.get("AVALON_PROJECT") - if PROJECT_PLUGINS_PATH and project_name: - for path in PROJECT_PLUGINS_PATH.split(os.pathsep): - if not path: - continue - plugin_path = os.path.join(path, project_name, "plugins") - if os.path.exists(plugin_path): - pyblish.register_plugin_path(plugin_path) - avalon.register_plugin_path(avalon.Loader, plugin_path) - avalon.register_plugin_path(avalon.Creator, plugin_path) - avalon.register_plugin_path( - avalon.InventoryAction, plugin_path - ) # Register studio specific plugins if STUDIO_PLUGINS_PATH and project_name: diff --git a/pype/hosts/celaction/api/cli.py b/pype/hosts/celaction/api/cli.py index 9f2d1a1fdb..476d2f69a9 100644 --- a/pype/hosts/celaction/api/cli.py +++ b/pype/hosts/celaction/api/cli.py @@ -102,14 +102,6 @@ def main(): pyblish.api.register_host(publish_host) - # Register project specific plugins - project_name = os.environ["AVALON_PROJECT"] - project_plugins_paths = os.getenv("PYPE_PROJECT_PLUGINS", "") - for path in project_plugins_paths.split(os.pathsep): - plugin_path = os.path.join(path, project_name, "plugins") - if os.path.exists(plugin_path): - pyblish.api.register_plugin_path(plugin_path) - return publish.show() diff --git a/pype/tools/standalonepublish/publish.py b/pype/tools/standalonepublish/publish.py index a4bb81ad3c..cfa9f8b8e8 100644 --- a/pype/tools/standalonepublish/publish.py +++ b/pype/tools/standalonepublish/publish.py @@ -19,14 +19,6 @@ def main(env): continue pyblish.api.register_plugin_path(path) - # Register project specific plugins - project_name = os.environ["AVALON_PROJECT"] - project_plugins_paths = env.get("PYPE_PROJECT_PLUGINS") or "" - for path in project_plugins_paths.split(os.pathsep): - plugin_path = os.path.join(path, project_name, "plugins") - if os.path.exists(plugin_path): - pyblish.api.register_plugin_path(plugin_path) - return publish.show() From 0b3953d39ec2c563c66787f517247cc0825e388f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:06:56 +0100 Subject: [PATCH 126/295] fix PUBLISH_PATH variable in celaction cli.py --- pype/hosts/celaction/api/cli.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pype/hosts/celaction/api/cli.py b/pype/hosts/celaction/api/cli.py index 476d2f69a9..f77bdea451 100644 --- a/pype/hosts/celaction/api/cli.py +++ b/pype/hosts/celaction/api/cli.py @@ -91,14 +91,9 @@ def main(): # Registers pype's Global pyblish plugins pype.install() - for path in PUBLISH_PATHS: - path = os.path.normpath(path) - - if not os.path.exists(path): - continue - - log.info(f"Registering path: {path}") - pyblish.api.register_plugin_path(path) + if os.path.exists(PUBLISH_PATH): + log.info(f"Registering path: {PUBLISH_PATH}") + pyblish.api.register_plugin_path(PUBLISH_PATH) pyblish.api.register_host(publish_host) From 960304a5dec66633f2bffa237997d0dbe77020c9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:09:28 +0100 Subject: [PATCH 127/295] removed usage of STUDIO_PLUGINS_PATH --- pype/__init__.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pype/__init__.py b/pype/__init__.py index 0add849457..216ec61784 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -13,8 +13,6 @@ pyblish = avalon = _original_discover = None log = logging.getLogger(__name__) -PROJECT_PLUGINS_PATH = os.environ.get("PYPE_PROJECT_PLUGINS") -STUDIO_PLUGINS_PATH = os.environ.get("PYPE_STUDIO_PLUGINS") PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__)) PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") @@ -101,17 +99,6 @@ def install(): project_name = os.environ.get("AVALON_PROJECT") - # Register studio specific plugins - if STUDIO_PLUGINS_PATH and project_name: - for path in STUDIO_PLUGINS_PATH.split(os.pathsep): - if not path: - continue - if os.path.exists(path): - pyblish.register_plugin_path(path) - avalon.register_plugin_path(avalon.Loader, path) - avalon.register_plugin_path(avalon.Creator, path) - avalon.register_plugin_path(avalon.InventoryAction, path) - if project_name: anatomy = Anatomy(project_name) anatomy.set_root_environments() From 1d279b301d0050fbd3d39ed0b0f4e9bec402853f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:09:43 +0100 Subject: [PATCH 128/295] register plugins from project settings on pype install --- pype/__init__.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/pype/__init__.py b/pype/__init__.py index 216ec61784..edd48a018d 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -1,12 +1,16 @@ # -*- coding: utf-8 -*- """Pype module.""" import os +import platform import functools import logging from .settings import get_project_settings -from .lib import Anatomy, filter_pyblish_plugins, \ +from .lib import ( + Anatomy, + filter_pyblish_plugins, change_timer_to_current_context +) pyblish = avalon = _original_discover = None @@ -99,10 +103,29 @@ def install(): project_name = os.environ.get("AVALON_PROJECT") + # Register studio specific plugins if project_name: anatomy = Anatomy(project_name) anatomy.set_root_environments() avalon.register_root(anatomy.roots) + + project_settings = get_project_settings(project_name) + platform_name = platform.system().lower() + project_plugins = ( + project_settings + .get("global", {}) + .get("project_plugins", {}) + .get(platform_name) + ) or [] + for path in project_plugins: + if not path or not os.path.exists(path): + continue + + pyblish.register_plugin_path(path) + avalon.register_plugin_path(avalon.Loader, path) + avalon.register_plugin_path(avalon.Creator, path) + avalon.register_plugin_path(avalon.InventoryAction, path) + # apply monkey patched discover to original one log.info("Patching discovery") avalon.discover = patched_discover From 1089c5f3c72655a51ff409f225c2eabcfad03340 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:28:15 +0100 Subject: [PATCH 129/295] it is possible to define project specific environments --- pype/settings/defaults/project_settings/global.json | 1 + .../schemas/projects_schema/schema_project_global.json | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index e252a103ac..fc8e7ddaf8 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -4,6 +4,7 @@ "darwin": [], "linux": [] }, + "project_environments": {}, "publish": { "IntegrateHeroVersion": { "enabled": true diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_global.json b/pype/settings/entities/schemas/projects_schema/schema_project_global.json index ebc8d08fb8..6e5cf0671c 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_global.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_global.json @@ -30,6 +30,12 @@ "multiplatform": true, "multipath": true, "use_label_wrap": true + }, + { + "key": "project_environments", + "type": "raw-json", + "label": "Additional Project Environments (set on application launch)", + "use_label_wrap": true } ] } From 71c9fb431a072d1dd5327589a988b325ce3189de Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:28:47 +0100 Subject: [PATCH 130/295] implemented function to apply project specific environments --- pype/lib/applications.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index abaecf1e9c..039b122bae 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -940,6 +940,19 @@ def prepare_host_environments(data): data["env"].update(final_env) +def apply_project_environments_value(project_name, env, project_settings=None): + import acre + + if project_settings is None: + project_settings = get_project_settings(project_name) + + env_value = project_settings["global"]["project_environments"] + if not env_value: + return env + parsed = acre.parse(env_value) + return _merge_env(parsed, env) + + def prepare_context_environments(data): """Modify launch environemnts with context data for launched host. @@ -964,6 +977,12 @@ def prepare_context_environments(data): ) return + # Load project specific environments + project_name = project_doc["name"] + data["env"] = apply_project_environments_value( + project_name, data["env"] + ) + app = data["app"] workdir_data = get_workdir_data( project_doc, asset_doc, task_name, app.host_name From 5793f9827398e5abaa0c8b3847256cee8b849cd3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:32:03 +0100 Subject: [PATCH 131/295] added some docstring --- pype/lib/applications.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 039b122bae..a03a845770 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -941,6 +941,20 @@ def prepare_host_environments(data): def apply_project_environments_value(project_name, env, project_settings=None): + """Apply project specific environments on passed environments. + + Args: + project_name (str): Name of project for which environemnts should be + received. + env (dict): Environment values on which project specific environments + will be applied. + project_settings (dict): Project settings for passed project name. + Optional if project settings are already prepared. + + Raises: + KeyError: If project settings do not contain keys for project specific + environments. + """ import acre if project_settings is None: From c98f4d83e7c57e9a5c9c083c4c5c058a75d9b612 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:44:53 +0100 Subject: [PATCH 132/295] standalone publisher sets project environments before publish is started --- .../tools/standalonepublish/widgets/widget_components.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/tools/standalonepublish/widgets/widget_components.py b/pype/tools/standalonepublish/widgets/widget_components.py index d4638ea437..d09c12f0ab 100644 --- a/pype/tools/standalonepublish/widgets/widget_components.py +++ b/pype/tools/standalonepublish/widgets/widget_components.py @@ -1,5 +1,4 @@ import os -import sys import json import tempfile import random @@ -10,7 +9,10 @@ from . import DropDataFrame from .constants import HOST_NAME from avalon import io from pype.api import execute, Logger -from pype.lib import get_pype_execute_args +from pype.lib import ( + get_pype_execute_args, + apply_project_environments_value +) log = Logger().get_logger("standalonepublisher") @@ -209,6 +211,9 @@ def cli_publish(data, publish_paths, gui=True): if data.get("family", "").lower() == "editorial": envcopy["PYBLISH_SUSPEND_LOGS"] = "1" + project_name = os.environ["AVALON_PROJECT"] + env_copy = apply_project_environments_value(project_name, envcopy) + args = get_pype_execute_args("run", PUBLISH_SCRIPT_PATH) result = execute(args, env=envcopy) From 6c74ea04d4aad48acc8354cbb11585d6eed1ca60 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:45:09 +0100 Subject: [PATCH 133/295] added new function to lib's init file --- pype/lib/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index 27dd93c1a1..2150e53b0e 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -81,6 +81,7 @@ from .applications import ( prepare_host_environments, prepare_context_environments, get_app_environments_for_context, + apply_project_environments_value, compile_list_of_regexes ) @@ -174,6 +175,7 @@ __all__ = [ "prepare_host_environments", "prepare_context_environments", "get_app_environments_for_context", + "apply_project_environments_value", "compile_list_of_regexes", From 6eb792144ba7ba1a240330fe4e93eb4442e9a41f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:57:58 +0100 Subject: [PATCH 134/295] removed celaction publish variant --- .../system_schema/host_settings/schema_celaction.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json index 6fa596808d..c5fe824f94 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json @@ -34,13 +34,6 @@ "app_name": "celation", "multiplatform": false, "multipath_executables": false - }, - { - "app_variant_label": "Publish", - "app_variant": "Publish", - "app_name": "celation", - "multiplatform": false, - "multipath_executables": false } ] } From 07fb6379263e1916a21f6d1b8b2fdea05bbc7e95 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 17:58:40 +0100 Subject: [PATCH 135/295] dashes are used as version serparators instead of underscore on apps --- .../system_settings/applications.json | 113 ++++++++---------- .../host_settings/schema_blender.json | 4 +- .../host_settings/schema_djv.json | 2 +- .../host_settings/schema_shell.json | 4 +- .../host_settings/schema_tvpaint.json | 4 +- .../host_settings/schema_unreal.json | 2 +- .../host_settings/template_nuke.json | 8 +- 7 files changed, 60 insertions(+), 77 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index 436ef62342..90e30c8a51 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -253,7 +253,7 @@ } }, "variants": { - "nuke_12_2": { + "nuke_12-2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -274,11 +274,11 @@ }, "environment": { "__environment_keys__": { - "nuke_12_2": [] + "nuke_12-2": [] } } }, - "nuke_12_0": { + "nuke_12-0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -299,11 +299,11 @@ }, "environment": { "__environment_keys__": { - "nuke_12_0": [] + "nuke_12-0": [] } } }, - "nuke_11_3": { + "nuke_11-3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -324,11 +324,11 @@ }, "environment": { "__environment_keys__": { - "nuke_11_3": [] + "nuke_11-3": [] } } }, - "nuke_11_2": { + "nuke_11-2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -347,7 +347,7 @@ }, "environment": { "__environment_keys__": { - "nuke_11_2": [] + "nuke_11-2": [] } } } @@ -377,7 +377,7 @@ } }, "variants": { - "nukex_12_2": { + "nukex_12-2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -404,11 +404,11 @@ }, "environment": { "__environment_keys__": { - "nukex_12_2": [] + "nukex_12-2": [] } } }, - "nukex_12_0": { + "nukex_12-0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -435,11 +435,11 @@ }, "environment": { "__environment_keys__": { - "nukex_12_0": [] + "nukex_12-0": [] } } }, - "nukex_11_3": { + "nukex_11-3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -466,11 +466,11 @@ }, "environment": { "__environment_keys__": { - "nukex_11_3": [] + "nukex_11-3": [] } } }, - "nukex_11_2": { + "nukex_11-2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -495,7 +495,7 @@ }, "environment": { "__environment_keys__": { - "nukex_11_2": [] + "nukex_11-2": [] } } } @@ -527,7 +527,7 @@ } }, "variants": { - "nukestudio_12_2": { + "nukestudio_12-2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -554,11 +554,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_12_2": [] + "nukestudio_12-2": [] } } }, - "nukestudio_12_0": { + "nukestudio_12-0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -585,11 +585,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_12_0": [] + "nukestudio_12-0": [] } } }, - "nukestudio_11_3": { + "nukestudio_11-3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -616,11 +616,11 @@ }, "environment": { "__environment_keys__": { - "nukestudio_11_3": [] + "nukestudio_11-3": [] } } }, - "nukestudio_11_2": { + "nukestudio_11-2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -643,7 +643,7 @@ }, "environment": { "__environment_keys__": { - "nukestudio_11_2": [] + "nukestudio_11-2": [] } } } @@ -675,7 +675,7 @@ } }, "variants": { - "hiero_12_2": { + "hiero_12-2": { "enabled": true, "label": "", "variant_label": "12.2", @@ -702,11 +702,11 @@ }, "environment": { "__environment_keys__": { - "hiero_12_2": [] + "hiero_12-2": [] } } }, - "hiero_12_0": { + "hiero_12-0": { "enabled": true, "label": "", "variant_label": "12.0", @@ -733,11 +733,11 @@ }, "environment": { "__environment_keys__": { - "hiero_12_0": [] + "hiero_12-0": [] } } }, - "hiero_11_3": { + "hiero_11-3": { "enabled": true, "label": "", "variant_label": "11.3", @@ -764,11 +764,11 @@ }, "environment": { "__environment_keys__": { - "hiero_11_3": [] + "hiero_11-3": [] } } }, - "hiero_11_2": { + "hiero_11-2": { "enabled": true, "label": "", "variant_label": "11.2", @@ -793,7 +793,7 @@ }, "environment": { "__environment_keys__": { - "hiero_11_2": [] + "hiero_11-2": [] } } } @@ -1057,7 +1057,7 @@ } }, "variants": { - "blender_2_83": { + "blender_2-83": { "enabled": true, "label": "", "variant_label": "2.83", @@ -1082,11 +1082,11 @@ }, "environment": { "__environment_keys__": { - "blender_2_83": [] + "blender_2-83": [] } } }, - "blender_2_90": { + "blender_2-90": { "enabled": true, "label": "", "variant_label": "2.90", @@ -1111,7 +1111,7 @@ }, "environment": { "__environment_keys__": { - "blender_2_90": [] + "blender_2-90": [] } } } @@ -1193,7 +1193,7 @@ } }, "variants": { - "tvpaint_animation_11_64bit": { + "tvpaint_animation_11-64bits": { "enabled": true, "label": "", "variant_label": "11 (64bits)", @@ -1212,11 +1212,11 @@ }, "environment": { "__environment_keys__": { - "tvpaint_animation_11_64bit": [] + "tvpaint_animation_11-64bits": [] } } }, - "tvpaint_animation_11_32bit": { + "tvpaint_animation_11-32bits": { "enabled": true, "label": "", "variant_label": "11 (32bits)", @@ -1235,7 +1235,7 @@ }, "environment": { "__environment_keys__": { - "tvpaint_animation_11_32bit": [] + "tvpaint_animation_11-32bits": [] } } } @@ -1407,23 +1407,6 @@ "celation_Local": [] } } - }, - "celation_Publish": { - "enabled": true, - "label": "", - "variant_label": "Pulblish", - "icon": "", - "executables": "", - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "celation_Publish": [] - } - } } } }, @@ -1445,7 +1428,7 @@ } }, "variants": { - "unreal_4_24": { + "unreal_4-24": { "enabled": true, "label": "", "variant_label": "4.24", @@ -1462,7 +1445,7 @@ }, "environment": { "__environment_keys__": { - "unreal_4_24": [] + "unreal_4-24": [] } } } @@ -1476,7 +1459,7 @@ } }, "variants": { - "python_python_3_7": { + "python_python_3-7": { "enabled": true, "label": "Python", "variant_label": "3.7", @@ -1493,11 +1476,11 @@ }, "environment": { "__environment_keys__": { - "python_python_3_7": [] + "python_python_3-7": [] } } }, - "python_python_2_7": { + "python_python_2-7": { "enabled": true, "label": "Python", "variant_label": "2.7", @@ -1514,7 +1497,7 @@ }, "environment": { "__environment_keys__": { - "python_python_2_7": [] + "python_python_2-7": [] } } }, @@ -1552,7 +1535,7 @@ } }, "variants": { - "djvview_1_1": { + "djvview_1-1": { "enabled": true, "label": "", "variant_label": "1.1", @@ -1569,7 +1552,7 @@ }, "environment": { "__environment_keys__": { - "djvview_1_1": [] + "djvview_1-1": [] } } } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json index 725a0685b6..5030f8280f 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json @@ -30,12 +30,12 @@ "template_data": [ { "app_variant_label": "2.83", - "app_variant": "2_83", + "app_variant": "2-83", "app_name": "blender" }, { "app_variant_label": "2.90", - "app_variant": "2_90", + "app_variant": "2-90", "app_name": "blender" } ] diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json index 8bbdb7ea9b..3f3af3585a 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json @@ -29,7 +29,7 @@ "name": "template_host_variant", "template_data": { "app_variant_label": "1.1", - "app_variant": "1_1", + "app_variant": "1-1", "app_name": "djvview" } } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json index f72450aa08..3288fe2ffb 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json @@ -25,12 +25,12 @@ "name": "template_host_variant", "template_data": [ { - "app_variant": "python_3_7", + "app_variant": "python_3-7", "app_variant_label": "Python 3.7", "app_name": "python" }, { - "app_variant": "python_2_7", + "app_variant": "python_2-7", "app_variant_label": "Python 2.7", "app_name": "python" }, diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json index a569ec0503..a3cc6188ac 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json @@ -30,12 +30,12 @@ "template_data": [ { "app_variant_label": "Animation 11 (64bits)", - "app_variant": "animation_11_64bit", + "app_variant": "animation_11-64bits", "app_name": "tvpaint" }, { "app_variant_label": "Animation 11 (32bits)", - "app_variant": "animation_11_32bit", + "app_variant": "animation_11-32bits", "app_name": "tvpaint" } ] diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json index b23a21b0fd..c79f08b71a 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json @@ -29,7 +29,7 @@ "name": "template_host_variant", "template_data": [ { - "app_variant": "4_24", + "app_variant": "4-24", "app_variant_label": "4.24", "app_name": "unreal" } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json index d32f87949d..c86c2aef61 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json @@ -30,22 +30,22 @@ "name": "template_host_variant", "template_data": [ { - "app_variant": "12_2", + "app_variant": "12-2", "app_variant_label": "12.2", "app_name": "{nuke_type}" }, { - "app_variant": "12_0", + "app_variant": "12-0", "app_variant_label": "12.0", "app_name": "{nuke_type}" }, { - "app_variant": "11_3", + "app_variant": "11-3", "app_variant_label": "11.3", "app_name": "{nuke_type}" }, { - "app_variant": "11_2", + "app_variant": "11-2", "app_variant_label": "11.2", "app_name": "{nuke_type}" } From 2fbe5d816558e7e995bc3ade8a09bb244e898c35 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:40:51 +0100 Subject: [PATCH 136/295] tools are dynamic dictionaries --- .../schemas/system_schema/schema_tools.json | 52 +++++++++---------- .../tool_settings/schema_arnold.json | 29 ----------- .../tool_settings/schema_vray.json | 29 ----------- .../tool_settings/schema_yeti.json | 29 ----------- .../tool_settings/template_tool_variant.json | 11 ---- 5 files changed, 25 insertions(+), 125 deletions(-) delete mode 100644 pype/settings/entities/schemas/system_schema/tool_settings/schema_arnold.json delete mode 100644 pype/settings/entities/schemas/system_schema/tool_settings/schema_vray.json delete mode 100644 pype/settings/entities/schemas/system_schema/tool_settings/schema_yeti.json delete mode 100644 pype/settings/entities/schemas/system_schema/tool_settings/template_tool_variant.json diff --git a/pype/settings/entities/schemas/system_schema/schema_tools.json b/pype/settings/entities/schemas/system_schema/schema_tools.json index 2c04abc47c..188d2fc8e8 100644 --- a/pype/settings/entities/schemas/system_schema/schema_tools.json +++ b/pype/settings/entities/schemas/system_schema/schema_tools.json @@ -1,37 +1,35 @@ { - "key": "tools", "type": "dict", - "label": "Tools", + "key": "tools", "collapsible": true, "is_file": true, "children": [ { - "type": "schema", - "name": "schema_arnold" - }, - { - "type": "schema", - "name": "schema_vray" - }, - { - "type": "schema", - "name": "schema_yeti" - }, - { - "type": "dict", - "key": "other", - "children": [ - { - "type": "schema_template", - "name": "template_tool_variant", - "template_data": [ - { - "tool_name": "othertools", - "tool_label": "Other Tools and Plugins" + "type": "dict-modifiable", + "label": "Tools", + "key": "tool_groups", + "collapsible_key": true, + "object_type": { + "type": "dict", + "children": [ + { + "key": "environment", + "label": "Environments", + "type": "raw-json" + }, + { + "type": "separator" + }, + { + "type": "dict-modifiable", + "key": "variants", + "label": "Variants", + "object_type": { + "type": "raw-json" } - ] - } - ] + } + ] + } } ] } diff --git a/pype/settings/entities/schemas/system_schema/tool_settings/schema_arnold.json b/pype/settings/entities/schemas/system_schema/tool_settings/schema_arnold.json deleted file mode 100644 index db2be09c83..0000000000 --- a/pype/settings/entities/schemas/system_schema/tool_settings/schema_arnold.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "dict", - "key": "mtoa", - "label": "Autodesk Arnold", - "collapsible": true, - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "key": "environment", - "label": "Environment (mtoa)", - "type": "raw-json", - "env_group_key": "mtoa" - }, - { - "type": "schema_template", - "name": "template_tool_variant", - "template_data": [ - { - "tool_label": "Arnold Versions" - } - ] - } - ] -} diff --git a/pype/settings/entities/schemas/system_schema/tool_settings/schema_vray.json b/pype/settings/entities/schemas/system_schema/tool_settings/schema_vray.json deleted file mode 100644 index 295b3ccac3..0000000000 --- a/pype/settings/entities/schemas/system_schema/tool_settings/schema_vray.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "dict", - "key": "vray", - "label": "Chaos Group Vray", - "collapsible": true, - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "key": "environment", - "label": "Environment", - "type": "raw-json", - "env_group_key": "vray" - }, - { - "type": "schema_template", - "name": "template_tool_variant", - "template_data": [ - { - "tool_label": "Vray Versions" - } - ] - } - ] -} diff --git a/pype/settings/entities/schemas/system_schema/tool_settings/schema_yeti.json b/pype/settings/entities/schemas/system_schema/tool_settings/schema_yeti.json deleted file mode 100644 index 34bb09da8d..0000000000 --- a/pype/settings/entities/schemas/system_schema/tool_settings/schema_yeti.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "dict", - "key": "yeti", - "label": "Pergrine Labs Yeti", - "collapsible": true, - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "key": "environment", - "label": "Environment", - "type": "raw-json", - "env_group_key": "yeti" - }, - { - "type": "schema_template", - "name": "template_tool_variant", - "template_data": [ - { - "tool_label": "Yeti Versions" - } - ] - } - ] -} diff --git a/pype/settings/entities/schemas/system_schema/tool_settings/template_tool_variant.json b/pype/settings/entities/schemas/system_schema/tool_settings/template_tool_variant.json deleted file mode 100644 index b0ba63469c..0000000000 --- a/pype/settings/entities/schemas/system_schema/tool_settings/template_tool_variant.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "type": "dict-modifiable", - "key": "variants", - "label": "{tool_label}", - "value_is_env_group": true, - "object_type": { - "type": "raw-json" - } - } -] From ddd5cbb13624360064fa19d7f50b9e6bf89e0387 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:42:06 +0100 Subject: [PATCH 137/295] changed exception type on root entity --- pype/settings/entities/root_entities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/root_entities.py b/pype/settings/entities/root_entities.py index 2d33689697..e7cb098c67 100644 --- a/pype/settings/entities/root_entities.py +++ b/pype/settings/entities/root_entities.py @@ -14,7 +14,7 @@ from .lib import ( get_project_settings_schema ) from .exceptions import ( - EntitySchemaError, + SchemaError, InvalidKeySymbols ) from pype.settings.constants import ( @@ -154,7 +154,7 @@ class RootEntity(BaseItemEntity): "Root entity \"{}\" has child with `is_group`" " attribute set to True but root can't save overrides." ).format(self.__class__.__name__) - raise EntitySchemaError(self, reason) + raise SchemaError(reason) child_entity.schema_validations() for key in self.non_gui_children.keys(): From c24ba96bea143802537979dbd2bcd9ada74dd0df Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:42:26 +0100 Subject: [PATCH 138/295] added schema validation on object_type key in mutable dict item --- pype/settings/entities/dict_mutable_keys_entity.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index 12a18ad612..b465171734 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -202,7 +202,7 @@ class DictMutableKeysEntity(EndpointEntity): self.schema_data.get("highlight_content") or False ) - object_type = self.schema_data["object_type"] + object_type = self.schema_data.get("object_type") or {} if not isinstance(object_type, dict): # Backwards compatibility object_type = { @@ -226,6 +226,12 @@ class DictMutableKeysEntity(EndpointEntity): def schema_validations(self): super(DictMutableKeysEntity, self).schema_validations() + if not self.schema_data.get("object_type"): + reason = ( + "Modifiable dictionary must have specified `object_type`." + ) + raise EntitySchemaError(self, reason) + # TODO Ability to store labels should be defined with different key if self.collapsible_key and not self.file_item: reason = ( From 9582d9ffdfb703e5bc35199c9c2baa3893c223a6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:42:38 +0100 Subject: [PATCH 139/295] resaved tools --- .../defaults/system_settings/tools.json | 113 +++++++----------- 1 file changed, 42 insertions(+), 71 deletions(-) diff --git a/pype/settings/defaults/system_settings/tools.json b/pype/settings/defaults/system_settings/tools.json index fce847fb55..4c9a90993f 100644 --- a/pype/settings/defaults/system_settings/tools.json +++ b/pype/settings/defaults/system_settings/tools.json @@ -1,78 +1,49 @@ { - "mtoa": { - "enabled": true, - "environment": { - "MTOA": "{PYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}", - "MAYA_RENDER_DESC_PATH": "{MTOA}", - "MAYA_MODULE_PATH": "{MTOA}", - "ARNOLD_PLUGIN_PATH": "{MTOA}/shaders", - "MTOA_EXTENSIONS_PATH": { - "darwin": "{MTOA}/extensions", - "linux": "{MTOA}/extensions", - "windows": "{MTOA}/extensions" + "tool_groups": { + "mtoa": { + "environment": { + "MTOA": "{PYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}", + "MAYA_RENDER_DESC_PATH": "{MTOA}", + "MAYA_MODULE_PATH": "{MTOA}", + "ARNOLD_PLUGIN_PATH": "{MTOA}/shaders", + "MTOA_EXTENSIONS_PATH": { + "darwin": "{MTOA}/extensions", + "linux": "{MTOA}/extensions", + "windows": "{MTOA}/extensions" + }, + "MTOA_EXTENSIONS": { + "darwin": "{MTOA}/extensions", + "linux": "{MTOA}/extensions", + "windows": "{MTOA}/extensions" + }, + "DYLD_LIBRARY_PATH": { + "darwin": "{MTOA}/bin" + }, + "PATH": { + "windows": "{PATH};{MTOA}/bin" + } }, - "MTOA_EXTENSIONS": { - "darwin": "{MTOA}/extensions", - "linux": "{MTOA}/extensions", - "windows": "{MTOA}/extensions" - }, - "DYLD_LIBRARY_PATH": { - "darwin": "{MTOA}/bin" - }, - "PATH": { - "windows": "{PATH};{MTOA}/bin" - }, - "__environment_keys__": { - "mtoa": [ - "MTOA", - "MAYA_RENDER_DESC_PATH", - "MAYA_MODULE_PATH", - "ARNOLD_PLUGIN_PATH", - "MTOA_EXTENSIONS_PATH", - "MTOA_EXTENSIONS", - "DYLD_LIBRARY_PATH", - "PATH" - ] + "variants": { + "mtoa_3-2": { + "MTOA_VERSION": "3.2" + }, + "mtoa_3-1": { + "MTOA_VERSION": "3.1" + } } }, - "variants": { - "mtoa_3_2": { - "MTOA_VERSION": "3.2", - "__environment_keys__": { - "mtoa_3_2": [ - "MTOA_VERSION" - ] - } - }, - "mtoa_3_1": { - "MTOA_VERSION": "3.1", - "__environment_keys__": { - "mtoa_3_1": [ - "MTOA_VERSION" - ] - } - } + "vray": { + "environment": {}, + "variants": {} + }, + "yeti": { + "environment": {}, + "variants": {} + }, + "__dynamic_keys_labels__": { + "mtoa": "Autodesk Arnold", + "yeti": "Pergrine Labs Yeti", + "vray": "Chaos Group Vray" } - }, - "vray": { - "enabled": true, - "environment": { - "__environment_keys__": { - "vray": [] - } - }, - "variants": {} - }, - "yeti": { - "enabled": true, - "environment": { - "__environment_keys__": { - "yeti": [] - } - }, - "variants": {} - }, - "other": { - "variants": {} } } \ No newline at end of file From 76bcca4c44aaada832304769d514dba5ed219209 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:42:53 +0100 Subject: [PATCH 140/295] changed how tools are used --- pype/lib/applications.py | 23 +++++++++-------------- pype/settings/entities/enum_entity.py | 12 +++++------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index abaecf1e9c..d62c5deff7 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -138,20 +138,16 @@ class ApplicationManager: app_group, app_name, host_name, app_data, self ) - tools_definitions = settings["tools"] + tools_definitions = settings["tools"]["tool_groups"] for tool_group_name, tool_group_data in tools_definitions.items(): - enabled = tool_group_data.get("enabled", True) tool_variants = tool_group_data.get("variants") or {} for tool_name, tool_data in tool_variants.items(): - if tool_name in self.tools: + tool = ApplicationTool(tool_name, tool_group_name) + if tool.full_name in self.tools: self.log.warning(( "Duplicated tool name in settings \"{}\"" - ).format(tool_name)) - - _enabled = tool_data.get("enabled", enabled) - self.tools[tool_name] = ApplicationTool( - tool_name, tool_group_name, _enabled - ) + ).format(tool.full_name)) + self.tools[tool.full_name] = tool def launch(self, app_name, **data): """Launch procedure. @@ -196,16 +192,15 @@ class ApplicationTool: Args: tool_name (str): Name of the tool. group_name (str): Name of group which wraps tool. - enabled (bool): Is tool enabled by studio. """ - def __init__(self, tool_name, group_name, enabled): + def __init__(self, tool_name, group_name): self.name = tool_name self.group_name = group_name - self.enabled = enabled - def __bool__(self): - return self.enabled + @property + def full_name(self): + return "/".join((self.group_name, self.name)) class ApplicationExecutable: diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index f06ec97f4b..ca0d5dec21 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -170,14 +170,12 @@ class ToolsEnumEntity(BaseEnumEntity): valid_keys = set() enum_items = [] - for tool_group in system_settings_entity["tools"].values(): - enabled_entity = tool_group.get("enabled") - if enabled_entity and not enabled_entity.value: - continue - + tools_entity = system_settings_entity["tools"] + for group_name, tool_group in tools_entity["tool_groups"].items(): for variant_name in tool_group["variants"].keys(): - enum_items.append({variant_name: variant_name}) - valid_keys.add(variant_name) + tool_name = "/".join((group_name, variant_name)) + enum_items.append({tool_name: tool_name}) + valid_keys.add(tool_name) return enum_items, valid_keys def set_override_state(self, *args, **kwargs): From e3c44925d48f4c8f1843a57116d429973f97bfa6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 25 Mar 2021 19:50:18 +0100 Subject: [PATCH 141/295] fix tool name in create update attriutes action --- .../event_handlers_user/action_create_cust_attrs.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py b/pype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py index ae040fd630..8ff0cade7b 100644 --- a/pype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py +++ b/pype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py @@ -400,11 +400,10 @@ class CustomAttributes(BaseAction): def tools_attribute(self, event): tools_data = [] - for tool_name, tool in self.app_manager.tools.items(): - if tool.enabled: - tools_data.append({ - tool_name: tool_name - }) + for tool_name in self.app_manager.tools.keys(): + tools_data.append({ + tool_name: tool_name + }) # Make sure there is at least one item if not tools_data: From 18a56ccce872c892de811092b03355b3f9808605 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 25 Mar 2021 23:11:25 +0100 Subject: [PATCH 142/295] update houdini menu --- pype/hosts/houdini/startup/MainMenuCommon.XML | 2 +- pype/hosts/houdini/startup/scripts/123.py | 4 +-- .../system_settings/applications.json | 25 ++++++++++++++++++- .../host_settings/schema_houdini.json | 4 +++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pype/hosts/houdini/startup/MainMenuCommon.XML b/pype/hosts/houdini/startup/MainMenuCommon.XML index 16e92be688..bfc7b6c0bc 100644 --- a/pype/hosts/houdini/startup/MainMenuCommon.XML +++ b/pype/hosts/houdini/startup/MainMenuCommon.XML @@ -2,7 +2,7 @@ - + Date: Thu, 25 Mar 2021 23:16:34 +0100 Subject: [PATCH 143/295] update workfiles tool in houdini --- pype/hosts/houdini/startup/MainMenuCommon.XML | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/houdini/startup/MainMenuCommon.XML b/pype/hosts/houdini/startup/MainMenuCommon.XML index bfc7b6c0bc..ba639a71a1 100644 --- a/pype/hosts/houdini/startup/MainMenuCommon.XML +++ b/pype/hosts/houdini/startup/MainMenuCommon.XML @@ -58,7 +58,7 @@ publish.show(parent) From 5d610145c6fe1b28f756bec7439a2ec620e699c1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 11:32:20 +0100 Subject: [PATCH 144/295] fix houdini defaults --- pype/settings/defaults/system_settings/applications.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index 1c080aa613..ea910e125d 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -992,7 +992,7 @@ } }, "variants": { - "houdini_18.5": { + "houdini_18-5": { "enabled": true, "label": "", "variant_label": "18.5", @@ -1011,7 +1011,7 @@ }, "environment": { "__environment_keys__": { - "houdini_18.5": [] + "houdini_18-5": [] } } }, From 8b4f462af9d999024479a565d7ff9518b95d04ae Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 11:33:30 +0100 Subject: [PATCH 145/295] removed "mtoa" from mtoa variants --- pype/settings/defaults/system_settings/tools.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/settings/defaults/system_settings/tools.json b/pype/settings/defaults/system_settings/tools.json index 4c9a90993f..215139468c 100644 --- a/pype/settings/defaults/system_settings/tools.json +++ b/pype/settings/defaults/system_settings/tools.json @@ -24,10 +24,10 @@ } }, "variants": { - "mtoa_3-2": { + "3-2": { "MTOA_VERSION": "3.2" }, - "mtoa_3-1": { + "3-1": { "MTOA_VERSION": "3.1" } } @@ -42,8 +42,8 @@ }, "__dynamic_keys_labels__": { "mtoa": "Autodesk Arnold", - "yeti": "Pergrine Labs Yeti", - "vray": "Chaos Group Vray" + "vray": "Chaos Group Vray", + "yeti": "Pergrine Labs Yeti" } } } \ No newline at end of file From 227e1aee1b44604aa253f86ece078ddf2ee7016a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 12:41:45 +0100 Subject: [PATCH 146/295] enhanced labels of tools in enum items --- pype/settings/entities/enum_entity.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index ca0d5dec21..8588cbb47c 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -172,9 +172,23 @@ class ToolsEnumEntity(BaseEnumEntity): enum_items = [] tools_entity = system_settings_entity["tools"] for group_name, tool_group in tools_entity["tool_groups"].items(): - for variant_name in tool_group["variants"].keys(): + group_label = None + if hasattr(tool_group, "get_key_label"): + group_label = tool_group.get_key_label(group_name) + + for variant_name, variant in tool_group["variants"].items(): + variant_label = None + if hasattr(variant, "get_key_label"): + variant_label = variant.get_key_label(variant_name) + + tool_label = None + if group_label and variant_label: + tool_label = " ".join((group_label, variant_label)) + tool_name = "/".join((group_name, variant_name)) - enum_items.append({tool_name: tool_name}) + if not tool_label: + tool_label = tool_name + enum_items.append({tool_name: tool_label}) valid_keys.add(tool_name) return enum_items, valid_keys From 604847758033753b6441555fb2ce4e0398384f3b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 12:49:08 +0100 Subject: [PATCH 147/295] removed variants label and variants are as collapsible keys --- pype/settings/defaults/system_settings/tools.json | 4 ++++ .../settings/entities/schemas/system_schema/schema_tools.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pype/settings/defaults/system_settings/tools.json b/pype/settings/defaults/system_settings/tools.json index 215139468c..214bfc95e5 100644 --- a/pype/settings/defaults/system_settings/tools.json +++ b/pype/settings/defaults/system_settings/tools.json @@ -29,6 +29,10 @@ }, "3-1": { "MTOA_VERSION": "3.1" + }, + "__dynamic_keys_labels__": { + "3-2": "3.2", + "3-1": "3.2" } } }, diff --git a/pype/settings/entities/schemas/system_schema/schema_tools.json b/pype/settings/entities/schemas/system_schema/schema_tools.json index 188d2fc8e8..2346bef36d 100644 --- a/pype/settings/entities/schemas/system_schema/schema_tools.json +++ b/pype/settings/entities/schemas/system_schema/schema_tools.json @@ -23,7 +23,7 @@ { "type": "dict-modifiable", "key": "variants", - "label": "Variants", + "collapsible_key": true, "object_type": { "type": "raw-json" } From d9c263be39d10cbd09900e04adb2f44f7d523155 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 12:49:25 +0100 Subject: [PATCH 148/295] fixed tools labels getting --- pype/settings/entities/enum_entity.py | 28 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index 8588cbb47c..c486de397e 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -170,24 +170,30 @@ class ToolsEnumEntity(BaseEnumEntity): valid_keys = set() enum_items = [] - tools_entity = system_settings_entity["tools"] - for group_name, tool_group in tools_entity["tool_groups"].items(): + tool_groups_entity = system_settings_entity["tools"]["tool_groups"] + for group_name, tool_group in tool_groups_entity.items(): + # Try to get group label from entity group_label = None - if hasattr(tool_group, "get_key_label"): - group_label = tool_group.get_key_label(group_name) + if hasattr(tool_groups_entity, "get_key_label"): + group_label = tool_groups_entity.get_key_label(group_name) - for variant_name, variant in tool_group["variants"].items(): + variants_entity = tool_group["variants"] + for variant_name in variants_entity.keys(): + # Prepare tool name (used as value) + tool_name = "/".join((group_name, variant_name)) + + # Try to get variant label from entity variant_label = None - if hasattr(variant, "get_key_label"): - variant_label = variant.get_key_label(variant_name) + if hasattr(variants_entity, "get_key_label"): + variant_label = variants_entity.get_key_label(variant_name) - tool_label = None + # Tool label that will be shown + # - use tool name itself if labels are not filled if group_label and variant_label: tool_label = " ".join((group_label, variant_label)) - - tool_name = "/".join((group_name, variant_name)) - if not tool_label: + else: tool_label = tool_name + enum_items.append({tool_name: tool_label}) valid_keys.add(tool_name) return enum_items, valid_keys From 5544f933104719ff1bed37396779f97b2bd02113 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 12:58:10 +0100 Subject: [PATCH 149/295] implemented prelaunch hook that will try to install PySide2 to blender --- .../hosts/blender/hooks/pre_pyside_install.py | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 pype/hosts/blender/hooks/pre_pyside_install.py diff --git a/pype/hosts/blender/hooks/pre_pyside_install.py b/pype/hosts/blender/hooks/pre_pyside_install.py new file mode 100644 index 0000000000..72a2f0d5c8 --- /dev/null +++ b/pype/hosts/blender/hooks/pre_pyside_install.py @@ -0,0 +1,138 @@ +import os +import subprocess +from pype.lib import PreLaunchHook + + +class InstallPySideToBlender(PreLaunchHook): + """Install Qt binding to blender's python packages. + + Prelaunch hook does 2 things: + 1.) Blender's python packages are pushed to the beginning of PYTHONPATH. + 2.) Check if blender has installed PySide2 and will try to install if not. + + For pipeline implementation is required to have Qt binding installed in + blender's python packages. + + Prelaunch hook can work only on Windows right now. + """ + + app_groups = ["blender"] + platforms = ["windows"] + + def execute(self): + # Get blender's python directory + executable = self.launch_context.executable.executable_path + # Blender installation contain subfolder named with it's version where + # python binaries are stored. + version_subfolder = self.launch_context.app_name.split("_")[1] + pythond_dir = os.path.join( + os.path.dirname(executable), + version_subfolder, + "python" + ) + + # Change PYTHONPATH to contain blender's packages as first + python_paths = [ + os.path.join(pythond_dir, "lib"), + os.path.join(pythond_dir, "lib", "site-packages"), + ] + python_path = self.launch_context.env.get("PYTHONPATH") or "" + for path in python_path.split(os.pathsep): + if path: + python_paths.append(path) + + self.launch_context.env["PYTHONPATH"] = os.pathsep.join(python_paths) + + # Get blender's python executable + python_executable = os.path.join(pythond_dir, "bin", "python.exe") + if not os.path.exists(python_executable): + self.log.warning( + "Couldn't find python executable for blender. {}".format( + executable + ) + ) + return + + # Check if PySide2 is installed and skip if yes + if self.is_pyside_installed(python_executable): + return + + # Install PySide2 in blender's python + self.install_pyside_windows(python_executable) + + def install_pyside_windows(self, python_executable): + """Install PySide2 python module to blender's python. + + Installation requires administration rights that's why it is required + to use "pywin32" module which can execute command's and ask for + administration rights. + """ + try: + import win32api + import win32con + import win32process + import win32event + import pywintypes + from win32comext.shell.shell import ShellExecuteEx + from win32comext.shell import shellcon + except Exception: + self.log.warning("Couldn't import \"pywin32\" modules") + return + + try: + # Parameters + # - use "-m pip" as module pip to install PySide2 and argument + # "--ignore-installed" is to force install module to blender's + # site-packages and make sure it is binary compatible + parameters = "-m pip install --ignore-installed PySide2" + + # Execute command and ask for administrator's rights + process_info = ShellExecuteEx( + nShow=win32con.SW_SHOWNORMAL, + fMask=shellcon.SEE_MASK_NOCLOSEPROCESS, + lpVerb="runas", + lpFile=python_executable, + lpParameters=parameters, + lpDirectory=os.path.dirname(python_executable) + ) + process_handle = process_info["hProcess"] + obj = win32event.WaitForSingleObject( + process_handle, win32event.INFINITE + ) + returncode = win32process.GetExitCodeProcess(process_handle) + if returncode == 0: + self.log.info( + "Successfully installed PySide2 module to blender." + ) + return + except pywintypes.error: + pass + + self.log.warning("Failed to instal PySide2 module to blender.") + + def is_pyside_installed(self, python_executable): + """Check if PySide2 module is in blender's pip list. + + Check that PySide2 is installed directly in blender's site-packages. + It is possible that it is installed in user's site-packages but that + may be incompatible with blender's python. + """ + # Get pip list from blender's python executable + args = [python_executable, "-m", "pip", "list"] + process = subprocess.Popen(args, stdout=subprocess.PIPE) + stdout, _ = process.communicate() + lines = stdout.decode().split("\r\n") + # Second line contain dashes that define maximum length of module name. + # Second column of dashes define maximum length of module version. + package_dashes, *_ = lines[1].split(" ") + package_len = len(package_dashes) + + # Got through printed lines starting at line 3 + for idx in range(2, len(lines)): + line = lines[idx] + if not line: + continue + package_name = line[0:package_len].strip() + if package_name.lower() == "pyside2": + return True + return False From 6520dd1b366fdc93f7c7f88ba511b2153a209fa3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 26 Mar 2021 13:03:30 +0100 Subject: [PATCH 150/295] make prelaunch hook not critical --- pype/hosts/blender/hooks/pre_pyside_install.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pype/hosts/blender/hooks/pre_pyside_install.py b/pype/hosts/blender/hooks/pre_pyside_install.py index 72a2f0d5c8..935105e895 100644 --- a/pype/hosts/blender/hooks/pre_pyside_install.py +++ b/pype/hosts/blender/hooks/pre_pyside_install.py @@ -20,6 +20,16 @@ class InstallPySideToBlender(PreLaunchHook): platforms = ["windows"] def execute(self): + # Prelaunch hook is not crutial + try: + self.inner_execute() + except Exception: + self.log.warning( + "Processing of {} crashed.".format(self.__class__.__name__), + exc_info=True + ) + + def inner_execute(self): # Get blender's python directory executable = self.launch_context.executable.executable_path # Blender installation contain subfolder named with it's version where From da23775c2524a3c544cbf4695316146f23644d05 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 26 Mar 2021 16:45:15 +0100 Subject: [PATCH 151/295] win: run mongo script improvements --- tools/run_mongo.ps1 | 61 ++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/tools/run_mongo.ps1 b/tools/run_mongo.ps1 index a72c8b1210..f04234d56a 100644 --- a/tools/run_mongo.ps1 +++ b/tools/run_mongo.ps1 @@ -37,37 +37,37 @@ function Exit-WithCode($exitcode) { function Find-Mongo { - Write-Host ">>> " -NoNewLine -ForegroundColor Green - Write-Host "Detecting MongoDB ... " -NoNewline - if (-not (Get-Command "mongod" -ErrorAction SilentlyContinue)) { - if(Test-Path 'C:\Program Files\MongoDB\Server\*\bin\mongod.exe' -PathType Leaf) { - # we have mongo server installed on standard Windows location - # so we can inject it to the PATH. We'll use latest version available. - $mongoVersions = Get-ChildItem -Directory 'C:\Program Files\MongoDB\Server' | Sort-Object -Property {$_.Name -as [int]} - if(Test-Path "$($mongoVersions[-1])\bin\mongod.exe" -PathType Leaf) { - $env:PATH="$($env:PATH);$($mongoVersions[-1])\bin\" - Write-Host "OK" -ForegroundColor Green - Write-Host " - auto-added from [ " -NoNewline - Write-Host "$($mongoVersions[-1])\bin\" -NoNewLine -ForegroundColor Cyan - Write-Host " ]" - } else { - Write-Host "FAILED " -NoNewLine -ForegroundColor Red - Write-Host "MongoDB not detected" -ForegroundColor Yellow - Write-Host "Tried to find it on standard location " -NoNewline -ForegroundColor Gray - Write-Host " [ " -NoNewline -ForegroundColor Cyan - Write-Host "$($mongoVersions[-1])\bin\" -NoNewline -ForegroundColor White - Write-Host " ] " -NonNewLine -ForegroundColor Cyan - Write-Host "but failed." -ForegroundColor Gray - Exit-WithCode 1 - } + $defaultPath = "C:\Program Files\MongoDB\Server" + Write-Host ">>> " -NoNewLine -ForegroundColor Green + Write-Host "Detecting MongoDB ... " -NoNewline + if (-not (Get-Command "mongod" -ErrorAction SilentlyContinue)) { + if(Test-Path "$($defaultPath)\*\bin\mongod.exe" -PathType Leaf) { + # we have mongo server installed on standard Windows location + # so we can inject it to the PATH. We'll use latest version available. + $mongoVersions = Get-ChildItem -Directory 'C:\Program Files\MongoDB\Server' | Sort-Object -Property {$_.Name -as [int]} + if(Test-Path "$($defaultPath)\$($mongoVersions[-1])\bin\mongod.exe" -PathType Leaf) { + $env:PATH="$($env:PATH);$($defaultPath)\$($mongoVersions[-1])\bin\" + Write-Host "OK" -ForegroundColor Green + Write-Host " - auto-added from [ " -NoNewline + Write-Host "$($defaultPath)\$($mongoVersions[-1])\bin\" -NoNewLine -ForegroundColor Cyan + Write-Host " ]" + } else { + Write-Host "FAILED " -NoNewLine -ForegroundColor Red + Write-Host "MongoDB not detected" -ForegroundColor Yellow + Write-Host "Tried to find it on standard location " -NoNewline -ForegroundColor Gray + Write-Host " [ " -NoNewline -ForegroundColor Cyan + Write-Host "$($defaultPath)\$($mongoVersions[-1])\bin\" -NoNewline -ForegroundColor White + Write-Host " ] " -NonNewLine -ForegroundColor Cyan + Write-Host "but failed." -ForegroundColor Gray + Exit-WithCode 1 + } } else { - Write-Host "FAILED " -NoNewLine -ForegroundColor Red - Write-Host "MongoDB not detected in PATH" -ForegroundColor Yellow - Exit-WithCode 1 + Write-Host "FAILED " -NoNewLine -ForegroundColor Red + Write-Host "MongoDB not detected in PATH" -ForegroundColor Yellow + Exit-WithCode 1 } - } else { - Write-Host "OK" -ForegroundColor Green + Write-Host "OK" -ForegroundColor Green } <# .SYNOPSIS @@ -90,4 +90,7 @@ $dbpath = (Get-Item $pype_root).parent.FullName + "\mongo_db_data" Find-Mongo $mongo = Get-Command "mongod" | Select-Object -ExpandProperty Definition -Start-Process -FilePath $mongo "--dbpath $($dbpath) --port $($port)" +$process = Start-Process -FilePath $mongo "--dbpath $($dbpath) --port $($port)" -PassThru -NoNewWindow -Wait +$process.WaitForExit() +Start-Process PowerShell -NoNewWindow -Wait + From b9a6e093abd0efe35b069b16d093948c1aa9f2da Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 26 Mar 2021 16:49:18 +0100 Subject: [PATCH 152/295] better handle connection errors to db --- start.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/start.py b/start.py index 8d60a14403..c231786797 100644 --- a/start.py +++ b/start.py @@ -100,6 +100,8 @@ import subprocess import site from pathlib import Path +from pymongo.errors import ServerSelectionTimeoutError + # add dependencies folder to sys.pat for frozen code if getattr(sys, 'frozen', False): frozen_libs = os.path.normpath( @@ -569,7 +571,13 @@ def boot(): # Get Pype path from database and set it to environment so Pype can # find its versions there and bootstrap them. - pype_path = get_pype_path_from_db(pype_mongo) + try: + pype_path = get_pype_path_from_db(pype_mongo) + except ServerSelectionTimeoutError as e: + print("!!! Can't connect to mongodb database server.") + print("!!! {}".format(e)) + sys.exit(1) + if not os.getenv("PYPE_PATH") and pype_path: os.environ["PYPE_PATH"] = pype_path From a427e96ecf34b6d03a9e71f35017c38af7c41836 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 26 Mar 2021 17:04:27 +0100 Subject: [PATCH 153/295] fixed broken tests --- tests/igniter/test_bootstrap_repos.py | 16 ++++++++-------- tests/igniter/test_tools.py | 4 ---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/igniter/test_bootstrap_repos.py b/tests/igniter/test_bootstrap_repos.py index 70edc5b89c..e1bdbffb30 100644 --- a/tests/igniter/test_bootstrap_repos.py +++ b/tests/igniter/test_bootstrap_repos.py @@ -145,18 +145,18 @@ def test_search_string_for_pype_version(printer): assert PypeVersion.version_in_str(ver_string[0])[0] == ver_string[1] +@pytest.mark.slow def test_install_live_repos(fix_bootstrap, printer): - rf = fix_bootstrap.create_version_from_live_code() + pype_version = fix_bootstrap.create_version_from_live_code() sep = os.path.sep expected_paths = [ - f"{rf}{sep}avalon-core", - f"{rf}{sep}avalon-unreal-integration", - f"{rf}{sep}maya-look-assigner", - f"{rf}{sep}pype" + f"{pype_version.path}{sep}avalon-core", + f"{pype_version.path}{sep}avalon-unreal-integration", + f"{pype_version.path}{sep}pype" ] printer("testing zip creation") - assert os.path.exists(rf), "zip archive was not created" - fix_bootstrap.add_paths_from_archive(rf) + assert os.path.exists(pype_version.path), "zip archive was not created" + fix_bootstrap.add_paths_from_archive(pype_version.path) for ep in expected_paths: assert ep in sys.path, f"{ep} not set correctly" @@ -168,7 +168,7 @@ def test_install_live_repos(fix_bootstrap, printer): print(pype.__file__) assert "pype" in sys.modules.keys(), "Pype not imported" assert sys.modules["pype"].__file__ == \ - f"{rf}{sep}pype{sep}pype{sep}__init__.py" + f"{pype_version.path}{sep}pype{sep}pype{sep}__init__.py" def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer): diff --git a/tests/igniter/test_tools.py b/tests/igniter/test_tools.py index b87900311a..0c7104f698 100644 --- a/tests/igniter/test_tools.py +++ b/tests/igniter/test_tools.py @@ -10,7 +10,3 @@ def test_validate_path_string(tmp_path): status2, _ = validate_path_string("booo" + str(uuid4())) assert status2 is False - # todo: change when Pype token is implemented - status3, reason = validate_path_string(str(uuid4())) - assert status3 is False - assert reason == "Not implemented yet" From 6cff8c514618ab2b37e04d4588902c51c239f685 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 26 Mar 2021 18:09:31 +0100 Subject: [PATCH 154/295] Nuke: adding keys and values to settings for Loaders --- .../defaults/project_settings/nuke.json | 52 ++++++++++++++++--- .../schemas/template_loader_plugin.json | 11 ++++ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/pype/settings/defaults/project_settings/nuke.json b/pype/settings/defaults/project_settings/nuke.json index f808f9caa5..d0b5ad0a7e 100644 --- a/pype/settings/defaults/project_settings/nuke.json +++ b/pype/settings/defaults/project_settings/nuke.json @@ -95,20 +95,60 @@ "load": { "LoadImage": { "enabled": true, - "representations": [] + "families": [ + "render2d", + "source", + "plate", + "render", + "prerender", + "review", + "image" + ], + "representations": [ + "exr", + "dpx", + "jpg", + "jpeg", + "png", + "psd" + ], + "node_name_template": "{class_name}_{ext}" }, "LoadMov": { "enabled": true, - "representations": [] + "families": [ + "source", + "plate", + "render", + "prerender", + "review" + ], + "representations": [ + "mov", + "review", + "mp4", + "h264" + ], + "node_name_template": "{class_name}_{ext}" }, "LoadSequence": { "enabled": true, + "families": [ + "render2d", + "source", + "plate", + "render", + "prerender", + "review" + ], "representations": [ - "png", - "jpg", "exr", - "" - ] + "dpx", + "jpg", + "jpeg", + "png" + ], + "node_name_template": "{class_name}_{ext}" } }, "workfile_build": { diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json index 20dca6df17..d01691ed5f 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json @@ -11,11 +11,22 @@ "key": "enabled", "label": "Enabled" }, + { + "type": "list", + "key": "families", + "label": "Families", + "object_type": "text" + }, { "type": "list", "key": "representations", "label": "Representations", "object_type": "text" + }, + { + "type": "text", + "key": "node_name_template", + "label": "Node name template" } ] } From 0d0dd262d35cce24c2e22df0f226ba155e3ad010 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 26 Mar 2021 18:09:56 +0100 Subject: [PATCH 155/295] Nuke: adding Loaders with template for name of node --- pype/hosts/nuke/plugins/load/load_image.py | 22 +++++++------ pype/hosts/nuke/plugins/load/load_mov.py | 31 +++++++++---------- pype/hosts/nuke/plugins/load/load_sequence.py | 20 ++++++++---- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/pype/hosts/nuke/plugins/load/load_image.py b/pype/hosts/nuke/plugins/load/load_image.py index dcaf31c9e3..7033cca9f8 100644 --- a/pype/hosts/nuke/plugins/load/load_image.py +++ b/pype/hosts/nuke/plugins/load/load_image.py @@ -12,11 +12,7 @@ from pype.hosts.nuke.api.lib import ( class LoadImage(api.Loader): """Load still image into Nuke""" - families = [ - "render2d", "source", "plate", - "render", "prerender", "review", - "image" - ] + families = ["render", "source", "plate", "review", "image"] representations = ["exr", "dpx", "jpg", "jpeg", "png", "psd"] label = "Load Image" @@ -24,6 +20,8 @@ class LoadImage(api.Loader): icon = "image" color = "white" + node_name_template = "{class_name}_{ext}" + options = [ qargparse.Integer( "frame_number", @@ -75,10 +73,16 @@ class LoadImage(api.Loader): frame, format(frame_number, "0{}".format(padding))) - read_name = "Read_{0}_{1}_{2}".format( - repr_cont["asset"], - repr_cont["subset"], - repr_cont["representation"]) + name_data = { + "asset": repr_cont["asset"], + "subset": repr_cont["subset"], + "representation": context["representation"]["name"], + "ext": repr_cont["representation"], + "id": context["representation"]["_id"], + "class_name": self.__class__.__name__ + } + + read_name = self.node_name_template.format(**name_data) # Create the Loader with the filename path set with viewer_update_and_undo_stop(): diff --git a/pype/hosts/nuke/plugins/load/load_mov.py b/pype/hosts/nuke/plugins/load/load_mov.py index 830359ccf9..0314322609 100644 --- a/pype/hosts/nuke/plugins/load/load_mov.py +++ b/pype/hosts/nuke/plugins/load/load_mov.py @@ -69,19 +69,8 @@ def add_review_presets_config(): class LoadMov(api.Loader): """Load mov file into Nuke""" - presets = add_review_presets_config() - families = [ - "source", - "plate", - "render", - "prerender", - "review"] + presets["families"] - - representations = [ - "mov", - "preview", - "review", - "mp4"] + presets["representations"] + families = ["render", "source", "plate", "review"] + representations = ["mov", "review", "mp4"] label = "Load mov" order = -10 @@ -90,6 +79,8 @@ class LoadMov(api.Loader): script_start = nuke.root()["first_frame"].value() + node_name_template = "{class_name}_{ext}" + def load(self, context, name, namespace, data): from avalon.nuke import ( containerise, @@ -133,10 +124,16 @@ class LoadMov(api.Loader): file = file.replace("\\", "/") - read_name = "Read_{0}_{1}_{2}".format( - repr_cont["asset"], - repr_cont["subset"], - repr_cont["representation"]) + name_data = { + "asset": repr_cont["asset"], + "subset": repr_cont["subset"], + "representation": context["representation"]["name"], + "ext": repr_cont["representation"], + "id": context["representation"]["_id"], + "class_name": self.__class__.__name__ + } + + read_name = self.node_name_template.format(**name_data) # Create the Loader with the filename path set with viewer_update_and_undo_stop(): diff --git a/pype/hosts/nuke/plugins/load/load_sequence.py b/pype/hosts/nuke/plugins/load/load_sequence.py index f99b7be52f..5cc2d019a0 100644 --- a/pype/hosts/nuke/plugins/load/load_sequence.py +++ b/pype/hosts/nuke/plugins/load/load_sequence.py @@ -72,14 +72,16 @@ def loader_shift(node, frame, relative=False): class LoadSequence(api.Loader): """Load image sequence into Nuke""" - families = ["render2d", "source", "plate", "render", "prerender", "review"] - representations = ["exr", "dpx", "jpg", "jpeg", "png"] + families = ["render", "source", "plate", "review"] + representations = ["exr", "dpx"] label = "Load Image Sequence" order = -20 icon = "file-video-o" color = "white" + node_name_template = "{class_name}_{ext}" + def load(self, context, name, namespace, data): from avalon.nuke import ( containerise, @@ -125,10 +127,16 @@ class LoadSequence(api.Loader): padding = len(frame) file = file.replace(frame, "#" * padding) - read_name = "Read_{0}_{1}_{2}".format( - repr_cont["asset"], - repr_cont["subset"], - context["representation"]["name"]) + name_data = { + "asset": repr_cont["asset"], + "subset": repr_cont["subset"], + "representation": context["representation"]["name"], + "ext": repr_cont["representation"], + "id": context["representation"]["_id"], + "class_name": self.__class__.__name__ + } + + read_name = self.node_name_template.format(**name_data) # Create the Loader with the filename path set with viewer_update_and_undo_stop(): From 73aeda9425dbc6cb29bba703c3937079e9c3af64 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 29 Mar 2021 12:18:06 +0200 Subject: [PATCH 156/295] implementing #1114 --- pype/hosts/nuke/api/lib.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/hosts/nuke/api/lib.py b/pype/hosts/nuke/api/lib.py index bea5df48cf..cee558f88f 100644 --- a/pype/hosts/nuke/api/lib.py +++ b/pype/hosts/nuke/api/lib.py @@ -489,6 +489,9 @@ def create_write_node(name, data, input=None, prenodes=None, review=True): # Deadline tab. add_deadline_tab(GN) + # open the AvalonTab as default + GN["AvalonTab"].setFlag(0) + # set tile color tile_color = _data.get("tile_color", "0xff0000ff") GN["tile_color"].setValue(tile_color) From e9b4e7ea4324aa3c9c9ffea7f179de9cd132445e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 29 Mar 2021 13:05:27 +0200 Subject: [PATCH 157/295] show error message as message in error detail --- pype/tools/pyblish_pype/model.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/tools/pyblish_pype/model.py b/pype/tools/pyblish_pype/model.py index ab05e7d665..b537d7724d 100644 --- a/pype/tools/pyblish_pype/model.py +++ b/pype/tools/pyblish_pype/model.py @@ -1013,7 +1013,9 @@ class TerminalModel(QtGui.QStandardItemModel): all_record_items = [] for record_item in record_items: record_type = record_item["type"] - + # Add error message to detail + if record_type == "error": + record_item["msg"] = record_item["label"] terminal_item_type = None if record_type == "record": for level, _type in self.level_to_record: From 449334dc624e28e7a11733e1908fe9c9a77c9e4f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 29 Mar 2021 13:31:48 +0200 Subject: [PATCH 158/295] Deadline: adding limit groups implementing #1167 --- .../plugins/publish/submit_nuke_deadline.py | 42 ++++++++++++++++--- .../defaults/project_settings/deadline.json | 3 +- .../schema_project_deadline.json | 9 ++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 60cc179a9b..a4653427bb 100644 --- a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -6,6 +6,7 @@ from avalon import api from avalon.vendor import requests import re import pyblish.api +import nuke class NukeSubmitDeadline(pyblish.api.InstancePlugin): @@ -29,6 +30,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): secondary_pool = "" group = "" department = "" + limit_groups = {} def process(self, instance): instance.data["toBeRenderedOn"] = "deadline" @@ -149,6 +151,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): if not priority: priority = self.priority + # resolve any limit groups + limit_groups = self.get_limit_groups() + self.log.info("Limit groups: `{}`".format(limit_groups)) + payload = { "JobInfo": { # Top-level group name @@ -180,7 +186,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): # Optional, enable double-click to preview rendered # frames from Deadline Monitor - "OutputFilename0": output_filename_0.replace("\\", "/") + "OutputFilename0": output_filename_0.replace("\\", "/"), + + # limiting groups + "LimitGroups": ",".join(limit_groups) }, "PluginInfo": { @@ -329,9 +338,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): return int(search_results[1]) if "#" in path: self.log.debug("_ path: `{}`".format(path)) - return path - else: - return path + return path def expected_files(self, instance, @@ -339,7 +346,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): """ Create expected files in instance data """ if not instance.data.get("expectedFiles"): - instance.data["expectedFiles"] = list() + instance.data["expectedFiles"] = [] dir = os.path.dirname(path) file = os.path.basename(path) @@ -356,3 +363,28 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): for i in range(self._frame_start, (self._frame_end + 1)): instance.data["expectedFiles"].append( os.path.join(dir, (file % i)).replace("\\", "/")) + + def get_limit_groups(self): + """Search for limit group nodes and return group name. + Limit groups will be defined as pairs in Nuke deadline submitter + presents where the key will be name of limit group and value will be + a list of plugin's node class names. Thus, when a plugin uses more + than one node, these will be captured and the triggered process + will add the appropriate limit group to the payload jobinfo attributes. + Returning: + list: captured groups list + """ + captured_groups = [] + for lg_name, list_node_class in self.deadline_limit_groups.items(): + for node_class in list_node_class: + for node in nuke.allNodes(recurseGroups=True): + # ignore all nodes not member of defined class + if node.Class() not in node_class: + continue + # ignore all disabled nodes + if node["disable"].value(): + continue + # add group name if not already added + if lg_name not in captured_groups: + captured_groups.append(lg_name) + return captured_groups diff --git a/pype/settings/defaults/project_settings/deadline.json b/pype/settings/defaults/project_settings/deadline.json index 6d36f38423..9ff551491c 100644 --- a/pype/settings/defaults/project_settings/deadline.json +++ b/pype/settings/defaults/project_settings/deadline.json @@ -20,7 +20,8 @@ "primary_pool": "", "secondary_pool": "", "group": "", - "department": "" + "department": "", + "limit_groups": {} }, "HarmonySubmitDeadline": { "enabled": true, diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 2070e4c8f5..f46221ba63 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -127,6 +127,15 @@ "type": "text", "key": "department", "label": "Department" + }, + { + "type": "dict-modifiable", + "key": "limit_groups", + "label": "Limit Groups", + "object_type": { + "type": "list", + "object_type": "text" + } } ] }, From 8d61529fb001c6aecdbb3b9c4903cf139ec8b721 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 29 Mar 2021 13:55:43 +0200 Subject: [PATCH 159/295] mimic source hierarchy in zips for frozen and live code --- igniter/bootstrap_repos.py | 139 ++++++++++---------------- igniter/tools.py | 5 + start.py | 14 +-- tests/igniter/test_bootstrap_repos.py | 13 ++- 4 files changed, 71 insertions(+), 100 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index 58d59afe88..2ef22ec4fa 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -242,7 +242,7 @@ class BootstrapRepos: self.registry = PypeSettingsRegistry() self.zip_filter = [".pyc", "__pycache__"] self.pype_filter = [ - "build", "docs", "tests", "repos", "tools", "venv" + "build", "docs", "tests", "tools", "venv", "coverage" ] self._message = message @@ -351,7 +351,7 @@ class BootstrapRepos: Path(temp_dir) / f"pype-v{version}.zip" self._print(f"creating zip: {temp_zip}") - self._create_pype_zip(temp_zip, repo_dir) + self._create_pype_zip(temp_zip, repo_dir.parent) if not os.path.exists(temp_zip): self._print("make archive failed.", LOG_ERROR) return None @@ -417,15 +417,14 @@ class BootstrapRepos: """ frozen_root = Path(sys.executable).parent - repo_dir = frozen_root / "repos" - repo_list = self._filter_dir( - repo_dir, self.zip_filter) # from frozen code we need igniter, pype, schema vendor pype_list = self._filter_dir( frozen_root / "pype", self.zip_filter) pype_list += self._filter_dir( frozen_root / "igniter", self.zip_filter) + pype_list += self._filter_dir( + frozen_root / "repos", self.zip_filter) pype_list += self._filter_dir( frozen_root / "schema", self.zip_filter) pype_list += self._filter_dir( @@ -443,17 +442,7 @@ class BootstrapRepos: with ZipFile(temp_zip, "w") as zip_file: progress = 0 - repo_inc = 48.0 / float(len(repo_list)) - file: Path - for file in repo_list: - progress += repo_inc - self._progress_callback(int(progress)) - - # archive name is relative to repos dir - arc_name = file.relative_to(repo_dir) - zip_file.write(file, arc_name) - - pype_inc = 48.0 / float(len(pype_list)) + pype_inc = 98.0 / float(len(pype_list)) file: Path for file in pype_list: progress += pype_inc @@ -463,17 +452,14 @@ class BootstrapRepos: # we need to replace first part of path which starts with # something like `exe.win/linux....` with `pype` as this # is expected by Pype in zip archive. - arc_name = Path("pype").joinpath(*arc_name.parts[1:]) + arc_name = Path().joinpath(*arc_name.parts[1:]) zip_file.write(file, arc_name) destination = self._move_zip_to_data_dir(temp_zip) return PypeVersion(version=version, path=destination) - def _create_pype_zip( - self, - zip_path: Path, include_dir: Path, - include_pype: bool = True) -> None: + def _create_pype_zip(self, zip_path: Path, pype_path: Path) -> None: """Pack repositories and Pype into zip. We are using :mod:`zipfile` instead :meth:`shutil.make_archive` @@ -482,70 +468,46 @@ class BootstrapRepos: and :attr:`pype_filter` on top level directory in Pype repository. Args: - zip_path (str): path to zip file. - include_dir (Path): repo directories to include. - include_pype (bool): add Pype module itself. + zip_path (Path): Path to zip file. + pype_path (Path): Path to Pype sources. """ - include_dir = include_dir.resolve() - pype_list = [] - # get filtered list of files in repositories (repos directory) - repo_list = self._filter_dir(include_dir, self.zip_filter) - # count them - repo_files = len(repo_list) - - # there must be some files, otherwise `include_dir` path is wrong - assert repo_files != 0, f"No repositories to include in {include_dir}" pype_inc = 0 - if include_pype: - # get filtered list of file in Pype repository - pype_list = self._filter_dir(include_dir.parent, self.zip_filter) - pype_files = len(pype_list) - repo_inc = 48.0 / float(repo_files) - pype_inc = 48.0 / float(pype_files) - else: - repo_inc = 98.0 / float(repo_files) + + # get filtered list of file in Pype repository + pype_list = self._filter_dir(pype_path, self.zip_filter) + pype_files = len(pype_list) + + pype_inc = 98.0 / float(pype_files) with ZipFile(zip_path, "w") as zip_file: progress = 0 + pype_root = pype_path.resolve() + # generate list of filtered paths + dir_filter = [pype_root / f for f in self.pype_filter] + file: Path - for file in repo_list: - progress += repo_inc + for file in pype_list: + progress += pype_inc self._progress_callback(int(progress)) - # archive name is relative to repos dir - arc_name = file.relative_to(include_dir) - zip_file.write(file, arc_name) + # if file resides in filtered path, skip it + is_inside = None + df: Path + for df in dir_filter: + try: + is_inside = file.resolve().relative_to(df) + except ValueError: + pass - # add pype itself - if include_pype: - pype_root = include_dir.parent.resolve() - # generate list of filtered paths - dir_filter = [pype_root / f for f in self.pype_filter] + if is_inside: + continue - file: Path - for file in pype_list: - progress += pype_inc - self._progress_callback(int(progress)) + processed_path = file + self._print(f"- processing {processed_path}") - # if file resides in filtered path, skip it - is_inside = None - df: Path - for df in dir_filter: - try: - is_inside = file.resolve().relative_to(df) - except ValueError: - pass - - if is_inside: - continue - - processed_path = file - self._print(f"- processing {processed_path}") - - zip_file.write(file, - "pype" / file.relative_to(pype_root)) + zip_file.write(file, file.relative_to(pype_root)) # test if zip is ok zip_file.testzip() @@ -553,10 +515,10 @@ class BootstrapRepos: @staticmethod def add_paths_from_archive(archive: Path) -> None: - """Add first-level directories as paths to :mod:`sys.path`. + """Add first-level directory and 'repos' as paths to :mod:`sys.path`. - This will enable Python to import modules is second-level directories - in zip file. + This will enable Python to import Pype and modules in `repos` + submodule directory in zip file. Adding to both `sys.path` and `PYTHONPATH`, skipping duplicates. @@ -574,21 +536,29 @@ class BootstrapRepos: name_list = zip_file.namelist() roots = [] + paths = [] for item in name_list: - root = item.split("/")[0] + if not item.startswith("repos/"): + continue + + root = item.split("/")[1] + if root not in roots: roots.append(root) - sys.path.insert(0, f"{archive}{os.path.sep}{root}") + paths.append( + f"{archive}{os.path.sep}repos{os.path.sep}{root}") + sys.path.insert(0, paths[-1]) + sys.path.insert(0, f"{archive}") pythonpath = os.getenv("PYTHONPATH", "") - paths = pythonpath.split(os.pathsep) - paths += roots + python_paths = pythonpath.split(os.pathsep) + python_paths += paths - os.environ["PYTHONPATH"] = os.pathsep.join(paths) + os.environ["PYTHONPATH"] = os.pathsep.join(python_paths) @staticmethod def add_paths_from_directory(directory: Path) -> None: - """Add first level directories as paths to :mod:`sys.path`. + """Add repos first level directories as paths to :mod:`sys.path`. This works the same as :meth:`add_paths_from_archive` but in specified directory. @@ -599,6 +569,8 @@ class BootstrapRepos: directory (Path): path to directory. """ + sys.path.insert(0, directory.as_posix()) + directory = directory / "repos" if not directory.exists() and not directory.is_dir(): raise ValueError("directory is invalid") @@ -937,8 +909,7 @@ class BootstrapRepos: try: # add one 'pype' level as inside dir there should # be many other repositories. - version_str = BootstrapRepos.get_version( - dir_item / "pype") + version_str = BootstrapRepos.get_version(dir_item) version_check = PypeVersion(version=version_str) except ValueError: self._print( @@ -979,7 +950,7 @@ class BootstrapRepos: try: with ZipFile(zip_item, "r") as zip_file: with zip_file.open( - "pype/pype/version.py") as version_file: + "pype/version.py") as version_file: zip_version = {} exec(version_file.read(), zip_version) version_check = PypeVersion( diff --git a/igniter/tools.py b/igniter/tools.py index 4ed4ae67f4..17e53a2b07 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -6,6 +6,7 @@ Functions ``compose_url()`` and ``decompose_url()`` are the same as in version is decided. """ +import sys from typing import Dict, Union from urllib.parse import urlparse, parse_qs from pathlib import Path @@ -244,6 +245,10 @@ def get_pype_path_from_db(url: str) -> Union[str, None]: try: client = MongoClient(**mongo_args) + except ServerSelectionTimeoutError as e: + print("!!! Can't connect to mongodb database server.") + print("!!! {}".format(e)) + return None except Exception: return None diff --git a/start.py b/start.py index c231786797..8553449489 100644 --- a/start.py +++ b/start.py @@ -100,7 +100,6 @@ import subprocess import site from pathlib import Path -from pymongo.errors import ServerSelectionTimeoutError # add dependencies folder to sys.pat for frozen code if getattr(sys, 'frozen', False): @@ -327,13 +326,12 @@ def _initialize_environment(pype_version: PypeVersion) -> None: # to same hierarchy from code and from frozen pype additional_paths = [ # add pype tools - os.path.join(os.environ["PYPE_ROOT"], "pype", "pype", "tools"), + os.path.join(os.environ["PYPE_ROOT"], "pype", "tools"), # add common pype vendor # (common for multiple Python interpreter versions) os.path.join( os.environ["PYPE_ROOT"], "pype", - "pype", "vendor", "python", "common" @@ -571,12 +569,10 @@ def boot(): # Get Pype path from database and set it to environment so Pype can # find its versions there and bootstrap them. - try: - pype_path = get_pype_path_from_db(pype_mongo) - except ServerSelectionTimeoutError as e: - print("!!! Can't connect to mongodb database server.") - print("!!! {}".format(e)) - sys.exit(1) + + pype_path = get_pype_path_from_db(pype_mongo) + if not pype_path: + print("*** Cannot get Pype path from database.") if not os.getenv("PYPE_PATH") and pype_path: os.environ["PYPE_PATH"] = pype_path diff --git a/tests/igniter/test_bootstrap_repos.py b/tests/igniter/test_bootstrap_repos.py index e1bdbffb30..75996b4026 100644 --- a/tests/igniter/test_bootstrap_repos.py +++ b/tests/igniter/test_bootstrap_repos.py @@ -150,9 +150,9 @@ def test_install_live_repos(fix_bootstrap, printer): pype_version = fix_bootstrap.create_version_from_live_code() sep = os.path.sep expected_paths = [ - f"{pype_version.path}{sep}avalon-core", - f"{pype_version.path}{sep}avalon-unreal-integration", - f"{pype_version.path}{sep}pype" + f"{pype_version.path}{sep}repos{sep}avalon-core", + f"{pype_version.path}{sep}repos{sep}avalon-unreal-integration", + f"{pype_version.path}" ] printer("testing zip creation") assert os.path.exists(pype_version.path), "zip archive was not created" @@ -165,10 +165,9 @@ def test_install_live_repos(fix_bootstrap, printer): import pype # noqa: F401 # test if pype is imported from specific location in zip - print(pype.__file__) assert "pype" in sys.modules.keys(), "Pype not imported" assert sys.modules["pype"].__file__ == \ - f"{pype_version.path}{sep}pype{sep}pype{sep}__init__.py" + f"{pype_version.path}{sep}pype{sep}__init__.py" def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer): @@ -252,7 +251,7 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer): def _create_valid_zip(path: Path, version: str): with ZipFile(path, "w") as zf: zf.writestr( - "pype/pype/version.py", f"__version__ = '{version}'\n\n") + "pype/version.py", f"__version__ = '{version}'\n\n") def _create_invalid_dir(path: Path): path.mkdir(parents=True, exist_ok=True) @@ -260,7 +259,7 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer): fp.write("invalid") def _create_valid_dir(path: Path, version: str): - pype_path = path / "pype" / "pype" + pype_path = path / "pype" version_path = pype_path / "version.py" pype_path.mkdir(parents=True, exist_ok=True) with open(version_path, "w") as fp: From 69962606eeece4da071ed47821e972ae98635f6c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 29 Mar 2021 13:56:21 +0200 Subject: [PATCH 160/295] partially revert changes in run_mongo --- tools/run_mongo.ps1 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/run_mongo.ps1 b/tools/run_mongo.ps1 index f04234d56a..66bd2656b9 100644 --- a/tools/run_mongo.ps1 +++ b/tools/run_mongo.ps1 @@ -45,19 +45,20 @@ function Find-Mongo { # we have mongo server installed on standard Windows location # so we can inject it to the PATH. We'll use latest version available. $mongoVersions = Get-ChildItem -Directory 'C:\Program Files\MongoDB\Server' | Sort-Object -Property {$_.Name -as [int]} - if(Test-Path "$($defaultPath)\$($mongoVersions[-1])\bin\mongod.exe" -PathType Leaf) { - $env:PATH="$($env:PATH);$($defaultPath)\$($mongoVersions[-1])\bin\" + if(Test-Path "$($mongoVersions[-1])\bin\mongod.exe" -PathType Leaf) { + $env:PATH = "$($env:PATH);$($mongoVersions[-1])\bin\" Write-Host "OK" -ForegroundColor Green Write-Host " - auto-added from [ " -NoNewline - Write-Host "$($defaultPath)\$($mongoVersions[-1])\bin\" -NoNewLine -ForegroundColor Cyan + Write-Host "$($mongoVersions[-1])\bin\mongod.exe" -NoNewLine -ForegroundColor Cyan Write-Host " ]" + return "$($mongoVersions[-1])\bin\mongod.exe" } else { Write-Host "FAILED " -NoNewLine -ForegroundColor Red Write-Host "MongoDB not detected" -ForegroundColor Yellow Write-Host "Tried to find it on standard location " -NoNewline -ForegroundColor Gray Write-Host " [ " -NoNewline -ForegroundColor Cyan - Write-Host "$($defaultPath)\$($mongoVersions[-1])\bin\" -NoNewline -ForegroundColor White - Write-Host " ] " -NonNewLine -ForegroundColor Cyan + Write-Host "$($mongoVersions[-1])\bin\mongod.exe" -NoNewline -ForegroundColor White + Write-Host " ] " -NoNewLine -ForegroundColor Cyan Write-Host "but failed." -ForegroundColor Gray Exit-WithCode 1 } @@ -68,6 +69,7 @@ function Find-Mongo { } } else { Write-Host "OK" -ForegroundColor Green + return Get-Command "mongod" -ErrorAction SilentlyContinue } <# .SYNOPSIS @@ -88,9 +90,7 @@ $port = 2707 # path to database $dbpath = (Get-Item $pype_root).parent.FullName + "\mongo_db_data" -Find-Mongo -$mongo = Get-Command "mongod" | Select-Object -ExpandProperty Definition -$process = Start-Process -FilePath $mongo "--dbpath $($dbpath) --port $($port)" -PassThru -NoNewWindow -Wait -$process.WaitForExit() -Start-Process PowerShell -NoNewWindow -Wait +$mongoPath = Find-Mongo +Start-Process -FilePath $mongopath "--dbpath $($dbpath) --port $($port)" -PassThru + From 6f68a7c38a8cca4fd6e81ab2e34a85e9f98c97f2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 29 Mar 2021 14:25:21 +0200 Subject: [PATCH 161/295] removed usage of settings for ftrack mongo names --- pype/modules/ftrack/lib/settings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/lib/settings.py b/pype/modules/ftrack/lib/settings.py index 4afac9c29f..46854e8184 100644 --- a/pype/modules/ftrack/lib/settings.py +++ b/pype/modules/ftrack/lib/settings.py @@ -1,5 +1,7 @@ from pype.api import get_system_settings +PYPE_DATABASE_NAME = "pype" + def get_ftrack_settings(): return get_system_settings()["modules"]["ftrack"] @@ -11,6 +13,6 @@ def get_ftrack_url_from_settings(): def get_ftrack_event_mongo_info(): ftrack_settings = get_ftrack_settings() - database_name = ftrack_settings["mongo_database_name"] - collection_name = ftrack_settings["mongo_collection_name"] + database_name = PYPE_DATABASE_NAME + collection_name = "ftrack_events" return database_name, collection_name From b29dbc15b9a38550d2ef7b2b842da48648a170f8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 29 Mar 2021 14:25:44 +0200 Subject: [PATCH 162/295] removed settings of ftrack mongo variables from settings --- .../defaults/system_settings/modules.json | 2 -- .../module_settings/schema_ftrack.json | 25 ++++--------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/pype/settings/defaults/system_settings/modules.json b/pype/settings/defaults/system_settings/modules.json index 8c4d7fe196..e285fce854 100644 --- a/pype/settings/defaults/system_settings/modules.json +++ b/pype/settings/defaults/system_settings/modules.json @@ -12,8 +12,6 @@ "ftrack_server": "https://pype.ftrackapp.com", "ftrack_actions_path": [], "ftrack_events_path": [], - "mongo_database_name": "pype", - "mongo_collection_name": "ftrack_events", "intent": { "items": { "-": "-", diff --git a/pype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json b/pype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json index 5647e14ebf..50ec330a11 100644 --- a/pype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json +++ b/pype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json @@ -35,24 +35,7 @@ "object_type": "text" }, { - "type": "splitter" - }, - { - "type": "label", - "label": "Ftrack event server advanced settings" - }, - { - "type": "text", - "key": "mongo_database_name", - "label": "Event Mongo DB" - }, - { - "type": "text", - "key": "mongo_collection_name", - "label": "Events Mongo Collection" - }, - { - "type": "splitter" + "type": "separator" }, { "key": "intent", @@ -71,13 +54,15 @@ "key": "items" }, { - "type": "label", - "label": " " + "type": "separator" }, { "key": "default", "type": "text", "label": "Default Intent" + }, + { + "type": "separator" } ] }, From 1c469d373086011daac423d51708f7396980ebe8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 29 Mar 2021 16:12:18 +0200 Subject: [PATCH 163/295] catch exceptions on save in settings ui --- .../settings/settings/widgets/categories.py | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/categories.py b/pype/tools/settings/settings/widgets/categories.py index 263012fa52..f1e154ee4d 100644 --- a/pype/tools/settings/settings/widgets/categories.py +++ b/pype/tools/settings/settings/widgets/categories.py @@ -260,14 +260,43 @@ class SettingsCategoryWidget(QtWidgets.QWidget): self.content_layout.addWidget(widget, 0) def save(self): - if self.items_are_valid(): + if not self.items_are_valid(): + return + + try: self.entity.save() + # NOTE There are relations to previous entities and C++ callbacks # so it is easier to just use new entity and recreate UI but # would be nice to change this and add cleanup part so this is # not required. self.reset() + except Exception as exc: + formatted_traceback = traceback.format_exception(*sys.exc_info()) + dialog = QtWidgets.QMessageBox(self) + msg = "Unexpected error happened!\n\nError: {}".format(str(exc)) + dialog.setText(msg) + dialog.setDetailedText("\n".join(formatted_traceback)) + dialog.setIcon(QtWidgets.QMessageBox.Critical) + + line_widths = set() + metricts = dialog.fontMetrics() + for line in formatted_traceback: + line_widths.add(metricts.width(line)) + max_width = max(line_widths) + + spacer = QtWidgets.QSpacerItem( + max_width, 0, + QtWidgets.QSizePolicy.Minimum, + QtWidgets.QSizePolicy.Expanding + ) + layout = dialog.layout() + layout.addItem( + spacer, layout.rowCount(), 0, 1, layout.columnCount() + ) + dialog.exec_() + def _create_root_entity(self): raise NotImplementedError( "`create_root_entity` method not implemented" From 48faec38032756ce6c9e6936ff48df01a624c9a7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 10:23:38 +0200 Subject: [PATCH 164/295] bulk mov instance collecting separated from batch instances --- .../publish/collect_batch_instances.py | 11 +-- .../publish/collect_bulk_mov_instances.py | 98 +++++++++++++++++++ 2 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 pype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py index 545efcb303..4ca1f72cc4 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py @@ -9,12 +9,11 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): label = "Collect Batch Instances" order = pyblish.api.CollectorOrder + 0.489 hosts = ["standalonepublisher"] - families = ["background_batch", "render_mov_batch"] + families = ["background_batch"] # presets default_subset_task = { - "background_batch": "background", - "render_mov_batch": "compositing" + "background_batch": "background" } subsets = { "background_batch": { @@ -30,12 +29,6 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): "task": "background", "family": "workfile" } - }, - "render_mov_batch": { - "renderCompositingDefault": { - "task": "compositing", - "family": "render" - } } } unchecked_by_default = [] diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py new file mode 100644 index 0000000000..cbb9d95e01 --- /dev/null +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py @@ -0,0 +1,98 @@ +import copy +import json +import pyblish.api + +from avalon import io +from pype.lib import get_subset_name + + +class CollectBulkMovInstances(pyblish.api.InstancePlugin): + """Collect all available instances for batch publish.""" + + label = "Collect Bulk Mov Instances" + order = pyblish.api.CollectorOrder + 0.489 + hosts = ["standalonepublisher"] + families = ["render_mov_batch"] + + new_instance_family = "render" + instance_task_names = [ + "compositing", + "comp" + ] + default_task_name = "compositing" + subset_name_variant = "Default" + + def process(self, instance): + context = instance.context + asset_name = instance.data["asset"] + + asset_doc = io.find_one( + { + "type": "asset", + "name": asset_name + }, + { + "_id": 1, + "data.tasks": 1 + } + ) + if not asset_doc: + raise AssertionError(( + "Couldn't find Asset document with name \"{}\"" + ).format(asset_name)) + + available_task_names = {} + asset_tasks = asset_doc.get("data", {}).get("tasks") or {} + for task_name in asset_tasks.keys(): + available_task_names[task_name.lower()] = task_name + + task_name = self.default_task_name + for _task_name in self.instance_task_names: + _task_name_low = _task_name.lower() + if _task_name_low in available_task_names: + task_name = available_task_names[_task_name_low] + break + + subset_name = get_subset_name( + self.new_instance_family, + self.subset_name_variant, + task_name, + asset_doc["_id"], + io.Session["AVALON_PROJECT"] + ) + instance_name = f"{asset_name}_{subset_name}" + + # create new instance + new_instance = context.create_instance(instance_name) + new_instance_data = { + "name": instance_name, + "label": instance_name, + "family": self.new_instance_family, + "subset": subset_name, + "task": task_name + } + new_instance.data.update(new_instance_data) + # add original instance data except name key + for key, value in instance.data.items(): + if key in new_instance_data: + continue + # Make sure value is copy since value may be object which + # can be shared across all new created objects + new_instance.data[key] = copy.deepcopy(value) + + # Add `render_mov_batch` for specific validators + if "families" not in new_instance.data: + new_instance.data["families"] = [] + new_instance.data["families"].append("render_mov_batch") + + # delete original instance + context.remove(instance) + + self.log.info(f"Created new instance: {instance_name}") + + def convertor(value): + return str(value) + + self.log.debug("Instance data: {}".format( + json.dumps(new_instance.data, indent=4, default=convertor) + )) From e22cb6a1f76b3075b74d2d2e50c804db62810f24 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 10:23:47 +0200 Subject: [PATCH 165/295] moved `get_subset_name` logic from pype.plugin to pype.lib --- pype/lib/__init__.py | 4 ++ pype/lib/plugin_tools.py | 81 ++++++++++++++++++++++++++++++++++++++++ pype/plugin.py | 72 ++--------------------------------- 3 files changed, 89 insertions(+), 68 deletions(-) diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index 2150e53b0e..f4282f7ea3 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -89,6 +89,8 @@ from .applications import ( from .profiles_filtering import filter_profiles from .plugin_tools import ( + TaskNotSetError, + get_subset_name, filter_pyblish_plugins, source_hash, get_unique_layer_name, @@ -181,6 +183,8 @@ __all__ = [ "filter_profiles", + "TaskNotSetError", + "get_subset_name", "filter_pyblish_plugins", "source_hash", "get_unique_layer_name", diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index c03d978ad4..0f3a0a2838 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -8,12 +8,93 @@ import json import tempfile from .execute import run_subprocess +from .profiles_filtering import filter_profiles from pype.settings import get_project_settings log = logging.getLogger(__name__) +# Subset name template used when plugin does not have defined any +DEFAULT_SUBSET_TEMPLATE = "{family}{Variant}" + + +class TaskNotSetError(KeyError): + def __init__(self, msg=None): + if not msg: + msg = "Creator's subset name template requires task name." + super(TaskNotSetError, self).__init__(msg) + + +def get_subset_name( + family, + variant, + task_name, + asset_id, + project_name=None, + host_name=None, + default_template=None +): + if not family: + return "" + + if not host_name: + host_name = os.environ["AVALON_APP"] + + # Use only last part of class family value split by dot (`.`) + family = family.rsplit(".", 1)[-1] + + # Get settings + tools_settings = get_project_settings(project_name)["global"]["tools"] + profiles = tools_settings["creator"]["subset_name_profiles"] + filtering_criteria = { + "families": family, + "hosts": host_name, + "tasks": task_name + } + + matching_profile = filter_profiles(profiles, filtering_criteria) + template = None + if matching_profile: + template = matching_profile["template"] + + # Make sure template is set (matching may have empty string) + if not template: + template = default_template or DEFAULT_SUBSET_TEMPLATE + + # Simple check of task name existence for template with {task} in + # - missing task should be possible only in Standalone publisher + if not task_name and "{task" in template.lower(): + raise TaskNotSetError() + + fill_pairs = ( + ("variant", variant), + ("family", family), + ("task", task_name) + ) + fill_data = {} + for key, value in fill_pairs: + # Handle cases when value is `None` (standalone publisher) + if value is None: + continue + # Keep value as it is + fill_data[key] = value + # Both key and value are with upper case + fill_data[key.upper()] = value.upper() + + # Capitalize only first char of value + # - conditions are because of possible index errors + capitalized = "" + if value: + # Upper first character + capitalized += value[0].upper() + # Append rest of string if there is any + if len(value) > 1: + capitalized += value[1:] + fill_data[key.capitalize()] = capitalized + + return template.format(**fill_data) + def filter_pyblish_plugins(plugins): """Filter pyblish plugins by presets. diff --git a/pype/plugin.py b/pype/plugin.py index 855b3371d3..111b65ade3 100644 --- a/pype/plugin.py +++ b/pype/plugin.py @@ -2,8 +2,8 @@ import tempfile import os import pyblish.api import avalon.api -from pype.api import get_project_settings -from pype.lib import filter_profiles + +from pype.lib import get_subset_name ValidatePipelineOrder = pyblish.api.ValidatorOrder + 0.05 ValidateContentsOrder = pyblish.api.ValidatorOrder + 0.1 @@ -11,83 +11,19 @@ ValidateSceneOrder = pyblish.api.ValidatorOrder + 0.2 ValidateMeshOrder = pyblish.api.ValidatorOrder + 0.3 -class TaskNotSetError(KeyError): - def __init__(self, msg=None): - if not msg: - msg = "Creator's subset name template requires task name." - super(TaskNotSetError, self).__init__(msg) - - class PypeCreatorMixin: """Helper to override avalon's default class methods. Mixin class must be used as first in inheritance order to override methods. """ - default_tempate = "{family}{Variant}" @classmethod def get_subset_name( cls, variant, task_name, asset_id, project_name, host_name=None ): - if not cls.family: - return "" - - if not host_name: - host_name = os.environ["AVALON_APP"] - - # Use only last part of class family value split by dot (`.`) - family = cls.family.rsplit(".", 1)[-1] - - # Get settings - tools_settings = get_project_settings(project_name)["global"]["tools"] - profiles = tools_settings["creator"]["subset_name_profiles"] - filtering_criteria = { - "families": family, - "hosts": host_name, - "tasks": task_name - } - - matching_profile = filter_profiles(profiles, filtering_criteria) - template = None - if matching_profile: - template = matching_profile["template"] - - # Make sure template is set (matching may have empty string) - if not template: - template = cls.default_tempate - - # Simple check of task name existence for template with {task} in - # - missing task should be possible only in Standalone publisher - if not task_name and "{task" in template.lower(): - raise TaskNotSetError() - - fill_pairs = ( - ("variant", variant), - ("family", family), - ("task", task_name) + return get_subset_name( + cls.family, variant, task_name, asset_id, project_name, host_name ) - fill_data = {} - for key, value in fill_pairs: - # Handle cases when value is `None` (standalone publisher) - if value is None: - continue - # Keep value as it is - fill_data[key] = value - # Both key and value are with upper case - fill_data[key.upper()] = value.upper() - - # Capitalize only first char of value - # - conditions are because of possible index errors - capitalized = "" - if value: - # Upper first character - capitalized += value[0].upper() - # Append rest of string if there is any - if len(value) > 1: - capitalized += value[1:] - fill_data[key.capitalize()] = capitalized - - return template.format(**fill_data) class Creator(PypeCreatorMixin, avalon.api.Creator): From f34d25f49b5a4a932688890f15813d32c8efbd8d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 10:25:06 +0200 Subject: [PATCH 166/295] implemented validator of task name existence on asset document --- .../publish/validate_task_existence.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py diff --git a/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py b/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py new file mode 100644 index 0000000000..8bd4fb997a --- /dev/null +++ b/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py @@ -0,0 +1,57 @@ +import collections +import pyblish.api +from avalon import io + + +class ValidateTaskExistence(pyblish.api.ContextPlugin): + """Validating tasks on instances are filled and existing.""" + + label = "Validate Task Existence" + order = pyblish.api.ValidatorOrder + + hosts = ["standalonepublisher"] + families = ["render_mov_batch"] + + def process(self, context): + asset_names = set() + for instance in context: + asset_names.add(instance.data["asset"]) + + asset_docs = io.find( + { + "type": "asset", + "name": {"$in": list(asset_names)} + }, + { + "name": 1, + "data.tasks": 1 + } + ) + tasks_by_asset_names = {} + for asset_doc in asset_docs: + asset_name = asset_doc["name"] + asset_tasks = asset_doc.get("data", {}).get("tasks") or {} + tasks_by_asset_names[asset_name] = list(asset_tasks.keys()) + + missing_tasks = [] + for instance in context: + asset_name = instance.data["asset"] + task_name = instance.data["task"] + task_names = tasks_by_asset_names.get(asset_name) or [] + if task_name and task_name in task_names: + continue + missing_tasks.append((asset_name, task_name)) + + # Everything is OK + if not missing_tasks: + return + + # Raise an exception + msg = "Couldn't find task name/s required for publishing.\n{}" + pair_msgs = [] + for missing_pair in missing_tasks: + pair_msgs.append( + "Asset: \"{}\" Task: \"{}\"".format(*missing_pair) + ) + + raise AssertionError(msg.format("\n".join(pair_msgs))) From 62db507459438e6fd42f52246d585dd8099a37ff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 10:28:27 +0200 Subject: [PATCH 167/295] removed unused import --- .../plugins/publish/validate_task_existence.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py b/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py index 8bd4fb997a..e3b2ae1646 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py +++ b/pype/hosts/standalonepublisher/plugins/publish/validate_task_existence.py @@ -1,4 +1,3 @@ -import collections import pyblish.api from avalon import io From bc09f31ddb96eec8fc754ff2aa57ae329a8d9e64 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 10:48:31 +0200 Subject: [PATCH 168/295] check for full match instead of simple match --- pype/lib/profiles_filtering.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/lib/profiles_filtering.py b/pype/lib/profiles_filtering.py index 32c17cbd12..455bb4cdd5 100644 --- a/pype/lib/profiles_filtering.py +++ b/pype/lib/profiles_filtering.py @@ -87,7 +87,7 @@ def validate_value_by_regexes(value, in_list): regexes = compile_list_of_regexes(in_list) for regex in regexes: - if re.match(regex, value): + if re.fullmatch(regex, value): return 1 return -1 From 687e7c619e74bfe105b2defa7d6caf9a6073acdd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 11:05:42 +0200 Subject: [PATCH 169/295] fix standalone publisher --- pype/tools/standalonepublish/widgets/widget_family.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/standalonepublish/widgets/widget_family.py b/pype/tools/standalonepublish/widgets/widget_family.py index 3150646624..3b590d3f97 100644 --- a/pype/tools/standalonepublish/widgets/widget_family.py +++ b/pype/tools/standalonepublish/widgets/widget_family.py @@ -9,7 +9,7 @@ from pype.api import ( get_project_settings, Creator ) -from pype.plugin import TaskNotSetError +from pype.lib import TaskNotSetError from avalon.tools.creator.app import SubsetAllowedSymbols From def94529b4b68f2bd1e2480d79907af5b3d93c31 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 14:04:24 +0200 Subject: [PATCH 170/295] aded python 2 compatibility for fullmatch --- pype/lib/profiles_filtering.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pype/lib/profiles_filtering.py b/pype/lib/profiles_filtering.py index 455bb4cdd5..c4410204dd 100644 --- a/pype/lib/profiles_filtering.py +++ b/pype/lib/profiles_filtering.py @@ -59,6 +59,14 @@ def _profile_exclusion(matching_profiles, logger): return matching_profiles[0][0] +def fullmatch(regex, string, flags=0): + """Emulate python-3.4 re.fullmatch().""" + matched = re.match(regex, string, flags=flags) + if matched and matched.span()[1] == len(string): + return matched + return None + + def validate_value_by_regexes(value, in_list): """Validates in any regex from list match entered value. @@ -87,7 +95,11 @@ def validate_value_by_regexes(value, in_list): regexes = compile_list_of_regexes(in_list) for regex in regexes: - if re.fullmatch(regex, value): + if hasattr(regex, "fullmatch"): + result = regex.fullmatch(value) + else: + result = fullmatch(regex, value) + if result: return 1 return -1 From d81625cf711befbfe1f4d56d00be3afcddcbcb84 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 14:50:24 +0200 Subject: [PATCH 171/295] reimplemented pype's workfiles tool in nuke --- pype/hosts/nuke/api/__init__.py | 2 +- pype/hosts/nuke/api/menu.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pype/hosts/nuke/api/__init__.py b/pype/hosts/nuke/api/__init__.py index 26a8248f01..6bf1ce888a 100644 --- a/pype/hosts/nuke/api/__init__.py +++ b/pype/hosts/nuke/api/__init__.py @@ -3,7 +3,7 @@ import sys import nuke from avalon import api as avalon -from avalon.tools import workfiles +from pype.tools import workfiles from pyblish import api as pyblish from pype.api import Logger import pype.hosts.nuke diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index 3f97cc228a..b5c4636d2d 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -1,15 +1,37 @@ +import os import nuke from avalon.api import Session from .lib import WorkfileSettings from pype.api import Logger, BuildWorkfile, get_current_project_settings +from pype.tools import workfiles log = Logger().get_logger(__name__) +def _show_workfiles(*args, **kwargs): + workfiles.show(os.environ["AVALON_WORKDIR"]) + + def install(): menubar = nuke.menu("Nuke") menu = menubar.findItem(Session["AVALON_LABEL"]) + + # replace reset resolution from avalon core to pype's + name = "Work Files..." + rm_item = [ + (i, item) for i, item in enumerate(menu.items()) if name in item.name() + ][0] + + log.debug("Changing Item: {}".format(rm_item)) + + menu.removeItem(rm_item[1].name()) + menu.addCommand( + name, + _show_workfiles, + index=(rm_item[0]) + ) + # replace reset resolution from avalon core to pype's name = "Reset Resolution" new_name = "Set Resolution" From 6d198ab4fac293fdec8e880214ca1699e38200fe Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 15:00:44 +0200 Subject: [PATCH 172/295] removed unnecessary function --- pype/hosts/nuke/api/menu.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index b5c4636d2d..7c3646c587 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -9,10 +9,6 @@ from pype.tools import workfiles log = Logger().get_logger(__name__) -def _show_workfiles(*args, **kwargs): - workfiles.show(os.environ["AVALON_WORKDIR"]) - - def install(): menubar = nuke.menu("Nuke") menu = menubar.findItem(Session["AVALON_LABEL"]) @@ -28,7 +24,7 @@ def install(): menu.removeItem(rm_item[1].name()) menu.addCommand( name, - _show_workfiles, + workfiles.show, index=(rm_item[0]) ) From c8e2e7744cd3749ff89e943099dabfdc935893cd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 15:48:16 +0200 Subject: [PATCH 173/295] remove unused import --- pype/hosts/nuke/api/menu.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index 7c3646c587..d638034809 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -1,4 +1,3 @@ -import os import nuke from avalon.api import Session From f8a220d4243e53c9ce3a574813f026dc80f28fe2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 30 Mar 2021 16:24:11 +0200 Subject: [PATCH 174/295] settings are stored as dictionaries instead of json string --- pype/settings/handlers.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 6e93f2f405..c801e9f17a 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -320,10 +320,15 @@ class CacheValues: self.creation_time = datetime.datetime.now() def update_from_document(self, document): - value = "{}" + data = {} if document: - value = document.get("value") or value - self.data = json.loads(value) + if "data" in document: + data = document["data"] + elif "value" in document: + value = document["value"] + if value: + data = json.loads(value) + self.data = data def to_json_string(self): return json.dumps(self.data or {}) @@ -415,7 +420,7 @@ class MongoSettingsHandler(SettingsHandler): }, { "type": SYSTEM_SETTINGS_KEY, - "value": self.system_settings_cache.to_json_string() + "data": self.system_settings_cache.data }, upsert=True ) @@ -550,7 +555,7 @@ class MongoSettingsHandler(SettingsHandler): } replace_data = { "type": doc_type, - "value": data_cache.to_json_string(), + "data": data_cache.data, "is_default": is_default } if not is_default: @@ -730,7 +735,7 @@ class MongoLocalSettingsHandler(LocalSettingsHandler): { "type": LOCAL_SETTING_KEY, "site_id": self.local_site_id, - "value": self.local_settings_cache.to_json_string() + "data": self.local_settings_cache.data }, upsert=True ) From fd6466082b86fe3dc5eb43838b9f8fbd89326117 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 30 Mar 2021 16:38:36 +0200 Subject: [PATCH 175/295] OTIO: adding python-2 version to `pype.vendor` --- .../python_2/opentimelineio/__init__.py | 51 + .../opentimelineio/adapters/__init__.py | 213 ++ .../opentimelineio/adapters/adapter.py | 317 +++ .../builtin_adapters.plugin_manifest.json | 31 + .../opentimelineio/adapters/cmx_3600.py | 1306 +++++++++++ .../opentimelineio/adapters/fcp_xml.py | 1941 +++++++++++++++++ .../opentimelineio/adapters/otio_json.py | 48 + .../opentimelineio/algorithms/__init__.py | 44 + .../opentimelineio/algorithms/filter.py | 275 +++ .../opentimelineio/algorithms/stack_algo.py | 138 ++ .../algorithms/timeline_algo.py | 56 + .../opentimelineio/algorithms/track_algo.py | 236 ++ .../opentimelineio/console/__init__.py | 40 + .../console/autogen_serialized_datamodel.py | 302 +++ .../opentimelineio/console/console_utils.py | 72 + .../opentimelineio/console/otiocat.py | 138 ++ .../opentimelineio/console/otioconvert.py | 259 +++ .../opentimelineio/console/otiostat.py | 193 ++ .../python_2/opentimelineio/core/__init__.py | 67 + .../opentimelineio/core/composable.py | 141 ++ .../opentimelineio/core/composition.py | 718 ++++++ .../python_2/opentimelineio/core/item.py | 243 +++ .../opentimelineio/core/json_serializer.py | 218 ++ .../opentimelineio/core/media_reference.py | 102 + .../core/serializable_object.py | 219 ++ .../opentimelineio/core/type_registry.py | 152 ++ .../opentimelineio/core/unknown_schema.py | 50 + .../python_2/opentimelineio/exceptions.py | 89 + .../python/python_2/opentimelineio/hooks.py | 174 ++ .../python_2/opentimelineio/media_linker.py | 169 ++ .../python_2/opentimelineio/opentime.py | 856 ++++++++ .../opentimelineio/plugins/__init__.py | 33 + .../opentimelineio/plugins/manifest.py | 282 +++ .../opentimelineio/plugins/python_plugin.py | 128 ++ .../opentimelineio/schema/__init__.py | 75 + .../python_2/opentimelineio/schema/clip.py | 130 ++ .../python_2/opentimelineio/schema/effect.py | 130 ++ .../schema/external_reference.py | 69 + .../python_2/opentimelineio/schema/gap.py | 82 + .../schema/generator_reference.py | 76 + .../python_2/opentimelineio/schema/marker.py | 128 ++ .../schema/missing_reference.py | 43 + .../opentimelineio/schema/schemadef.py | 65 + .../schema/serializable_collection.py | 149 ++ .../python_2/opentimelineio/schema/stack.py | 120 + .../opentimelineio/schema/timeline.py | 133 ++ .../python_2/opentimelineio/schema/track.py | 242 ++ .../opentimelineio/schema/transition.py | 159 ++ .../opentimelineio/schemadef/__init__.py | 5 + .../python_2/opentimelineio/test_utils.py | 54 + .../opentimelineio_contrib/__init__.py | 37 + .../adapters/__init__.py | 0 .../adapters/aaf_adapter/__init__.py | 0 .../adapters/aaf_adapter/aaf_writer.py | 764 +++++++ .../adapters/advanced_authoring_format.py | 979 +++++++++ .../opentimelineio_contrib/adapters/ale.py | 318 +++ .../adapters/burnins.py | 93 + .../contrib_adapters.plugin_manifest.json | 61 + .../adapters/extern_maya_sequencer.py | 261 +++ .../adapters/extern_rv.py | 327 +++ .../adapters/fcpx_xml.py | 1182 ++++++++++ .../adapters/ffmpeg_burnins.py | 424 ++++ .../adapters/hls_playlist.py | 1781 +++++++++++++++ .../adapters/maya_sequencer.py | 132 ++ .../opentimelineio_contrib/adapters/rv.py | 84 + .../opentimelineio_contrib/adapters/xges.py | 819 +++++++ 66 files changed, 18223 insertions(+) create mode 100644 pype/vendor/python/python_2/opentimelineio/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/adapter.py create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/builtin_adapters.plugin_manifest.json create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/cmx_3600.py create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/fcp_xml.py create mode 100644 pype/vendor/python/python_2/opentimelineio/adapters/otio_json.py create mode 100644 pype/vendor/python/python_2/opentimelineio/algorithms/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/algorithms/filter.py create mode 100644 pype/vendor/python/python_2/opentimelineio/algorithms/stack_algo.py create mode 100644 pype/vendor/python/python_2/opentimelineio/algorithms/timeline_algo.py create mode 100644 pype/vendor/python/python_2/opentimelineio/algorithms/track_algo.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/autogen_serialized_datamodel.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/console_utils.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/otiocat.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/otioconvert.py create mode 100644 pype/vendor/python/python_2/opentimelineio/console/otiostat.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/composable.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/composition.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/item.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/json_serializer.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/media_reference.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/serializable_object.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/type_registry.py create mode 100644 pype/vendor/python/python_2/opentimelineio/core/unknown_schema.py create mode 100644 pype/vendor/python/python_2/opentimelineio/exceptions.py create mode 100644 pype/vendor/python/python_2/opentimelineio/hooks.py create mode 100644 pype/vendor/python/python_2/opentimelineio/media_linker.py create mode 100644 pype/vendor/python/python_2/opentimelineio/opentime.py create mode 100644 pype/vendor/python/python_2/opentimelineio/plugins/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/plugins/manifest.py create mode 100644 pype/vendor/python/python_2/opentimelineio/plugins/python_plugin.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/clip.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/effect.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/external_reference.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/gap.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/generator_reference.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/marker.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/missing_reference.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/schemadef.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/serializable_collection.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/stack.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/timeline.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/track.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schema/transition.py create mode 100644 pype/vendor/python/python_2/opentimelineio/schemadef/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio/test_utils.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/__init__.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/advanced_authoring_format.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/ale.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/burnins.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/contrib_adapters.plugin_manifest.json create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_maya_sequencer.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_rv.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/fcpx_xml.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/ffmpeg_burnins.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/hls_playlist.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/maya_sequencer.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/rv.py create mode 100644 pype/vendor/python/python_2/opentimelineio_contrib/adapters/xges.py diff --git a/pype/vendor/python/python_2/opentimelineio/__init__.py b/pype/vendor/python/python_2/opentimelineio/__init__.py new file mode 100644 index 0000000000..a8b0a636ad --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/__init__.py @@ -0,0 +1,51 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""An editorial interchange format and library. + +see: http://opentimeline.io + +.. moduleauthor:: Pixar Animation Studios +""" + +# flake8: noqa + +# in dependency hierarchy +from . import ( + opentime, + exceptions, + core, + schema, + schemadef, + plugins, + media_linker, + adapters, + hooks, + algorithms, +) + +__version__ = "0.11.0" +__author__ = "Pixar Animation Studios" +__author_email__ = "opentimelineio@pixar.com" +__license__ = "Modified Apache 2.0 License" diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/__init__.py b/pype/vendor/python/python_2/opentimelineio/adapters/__init__.py new file mode 100644 index 0000000000..afbe3f8e8a --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/__init__.py @@ -0,0 +1,213 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Expose the adapter interface to developers. + +To read from an existing representation, use the read_from_string and +read_from_file functions. To query the list of adapters, use the +available_adapter_names function. + +The otio_json adapter is provided as a the canonical, lossless, serialization +of the in-memory otio schema. Other adapters are to varying degrees lossy. +For more information, consult the documentation in the individual adapter +modules. +""" + +import os +import itertools + +from .. import ( + exceptions, + plugins, + media_linker +) + +from .adapter import Adapter # noqa + +# OTIO Json adapter is always available +from . import otio_json # noqa + + +def suffixes_with_defined_adapters(read=False, write=False): + """Return a set of all the suffixes that have adapters defined for them.""" + + if not read and not write: + read = True + write = True + + positive_adapters = [] + for adp in plugins.ActiveManifest().adapters: + if read and adp.has_feature("read"): + positive_adapters.append(adp) + continue + + if write and adp.has_feature("write"): + positive_adapters.append(adp) + + return set( + itertools.chain.from_iterable( + adp.suffixes for adp in positive_adapters + ) + ) + + +def available_adapter_names(): + """Return a string list of the available adapters.""" + + return [str(adp.name) for adp in plugins.ActiveManifest().adapters] + + +def _from_filepath_or_name(filepath, adapter_name): + if adapter_name is not None: + return plugins.ActiveManifest().from_name(adapter_name) + else: + return from_filepath(filepath) + + +def from_filepath(filepath): + """Guess the adapter object to use for a given filepath. + + example: + "foo.otio" returns the "otio_json" adapter. + """ + + outext = os.path.splitext(filepath)[1][1:] + + try: + return plugins.ActiveManifest().from_filepath(outext) + except exceptions.NoKnownAdapterForExtensionError: + raise exceptions.NoKnownAdapterForExtensionError( + "No adapter for suffix '{}' on file '{}'".format( + outext, + filepath + ) + ) + + +def from_name(name): + """Fetch the adapter object by the name of the adapter directly.""" + + try: + return plugins.ActiveManifest().from_name(name) + except exceptions.NotSupportedError: + raise exceptions.NotSupportedError( + "adapter not supported: {}, available: {}".format( + name, + available_adapter_names() + ) + ) + + +def read_from_file( + filepath, + adapter_name=None, + media_linker_name=media_linker.MediaLinkingPolicy.ForceDefaultLinker, + media_linker_argument_map=None, + **adapter_argument_map +): + """Read filepath using adapter_name. + + If adapter_name is None, try and infer the adapter name from the filepath. + + For example: + timeline = read_from_file("example_trailer.otio") + timeline = read_from_file("file_with_no_extension", "cmx_3600") + """ + + adapter = _from_filepath_or_name(filepath, adapter_name) + + return adapter.read_from_file( + filepath=filepath, + media_linker_name=media_linker_name, + media_linker_argument_map=media_linker_argument_map, + **adapter_argument_map + ) + + +def read_from_string( + input_str, + adapter_name='otio_json', + media_linker_name=media_linker.MediaLinkingPolicy.ForceDefaultLinker, + media_linker_argument_map=None, + **adapter_argument_map +): + """Read a timeline from input_str using adapter_name. + + This is useful if you obtain a timeline from someplace other than the + filesystem. + + Example: + raw_text = urlopen(my_url).read() + timeline = read_from_string(raw_text, "otio_json") + """ + + adapter = plugins.ActiveManifest().from_name(adapter_name) + return adapter.read_from_string( + input_str=input_str, + media_linker_name=media_linker_name, + media_linker_argument_map=media_linker_argument_map, + **adapter_argument_map + ) + + +def write_to_file( + input_otio, + filepath, + adapter_name=None, + **adapter_argument_map +): + """Write input_otio to filepath using adapter_name. + + If adapter_name is None, infer the adapter_name to use based on the + filepath. + + Example: + otio.adapters.write_to_file(my_timeline, "output.otio") + """ + + adapter = _from_filepath_or_name(filepath, adapter_name) + + return adapter.write_to_file( + input_otio=input_otio, + filepath=filepath, + **adapter_argument_map + ) + + +def write_to_string( + input_otio, + adapter_name='otio_json', + **adapter_argument_map +): + """Return input_otio written to a string using adapter_name. + + Example: + raw_text = otio.adapters.write_to_string(my_timeline, "otio_json") + """ + + adapter = plugins.ActiveManifest().from_name(adapter_name) + return adapter.write_to_string( + input_otio=input_otio, + **adapter_argument_map + ) diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/adapter.py b/pype/vendor/python/python_2/opentimelineio/adapters/adapter.py new file mode 100644 index 0000000000..82ac405065 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/adapter.py @@ -0,0 +1,317 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of the OTIO internal `Adapter` system. + +For information on writing adapters, please consult: + https://opentimelineio.readthedocs.io/en/latest/tutorials/write-an-adapter.html# # noqa +""" + +from .. import ( + core, + plugins, + media_linker, + hooks, +) + + +@core.register_type +class Adapter(plugins.PythonPlugin): + """Adapters convert between OTIO and other formats. + + Note that this class is not subclassed by adapters. Rather, an adapter is + a python module that implements at least one of the following functions: + + write_to_string(input_otio) + write_to_file(input_otio, filepath) (optionally inferred) + read_from_string(input_str) + read_from_file(filepath) (optionally inferred) + + ...as well as a small json file that advertises the features of the adapter + to OTIO. This class serves as the wrapper around these modules internal + to OTIO. You should not need to extend this class to create new adapters + for OTIO. + + For more information: + https://opentimelineio.readthedocs.io/en/latest/tutorials/write-an-adapter.html# # noqa + """ + _serializable_label = "Adapter.1" + + def __init__( + self, + name=None, + execution_scope=None, + filepath=None, + suffixes=None + ): + plugins.PythonPlugin.__init__( + self, + name, + execution_scope, + filepath + ) + + self.suffixes = suffixes or [] + + suffixes = core.serializable_field( + "suffixes", + type([]), + doc="File suffixes associated with this adapter." + ) + + def has_feature(self, feature_string): + """ + return true if adapter supports feature_string, which must be a key + of the _FEATURE_MAP dictionary. + + Will trigger a call to self.module(), which imports the plugin. + """ + + if feature_string.lower() not in _FEATURE_MAP: + return False + + search_strs = _FEATURE_MAP[feature_string] + + try: + return any(hasattr(self.module(), s) for s in search_strs) + except ImportError: + # @TODO: should issue a warning that the plugin was not importable? + return False + + def read_from_file( + self, + filepath, + media_linker_name=media_linker.MediaLinkingPolicy.ForceDefaultLinker, + media_linker_argument_map=None, + hook_function_argument_map={}, + **adapter_argument_map + ): + """Execute the read_from_file function on this adapter. + + If read_from_string exists, but not read_from_file, execute that with + a trivial file object wrapper. + """ + + if media_linker_argument_map is None: + media_linker_argument_map = {} + + result = None + + if ( + not self.has_feature("read_from_file") and + self.has_feature("read_from_string") + ): + with open(filepath, 'r') as fo: + contents = fo.read() + result = self._execute_function( + "read_from_string", + input_str=contents, + **adapter_argument_map + ) + else: + result = self._execute_function( + "read_from_file", + filepath=filepath, + **adapter_argument_map + ) + + hook_function_argument_map['adapter_arguments'] = adapter_argument_map + hook_function_argument_map['media_linker_argument_map'] = \ + media_linker_argument_map + result = hooks.run("post_adapter_read", result, + extra_args=hook_function_argument_map) + + if media_linker_name and ( + media_linker_name != media_linker.MediaLinkingPolicy.DoNotLinkMedia + ): + _with_linked_media_references( + result, + media_linker_name, + media_linker_argument_map + ) + + result = hooks.run("post_media_linker", result, + extra_args=media_linker_argument_map) + + return result + + def write_to_file( + self, + input_otio, + filepath, + hook_function_argument_map={}, + **adapter_argument_map + ): + """Execute the write_to_file function on this adapter. + + If write_to_string exists, but not write_to_file, execute that with + a trivial file object wrapper. + """ + hook_function_argument_map['adapter_arguments'] = adapter_argument_map + input_otio = hooks.run("pre_adapter_write", input_otio, + extra_args=hook_function_argument_map) + + if ( + not self.has_feature("write_to_file") and + self.has_feature("write_to_string") + ): + result = self.write_to_string(input_otio, **adapter_argument_map) + with open(filepath, 'w') as fo: + fo.write(result) + return filepath + + return self._execute_function( + "write_to_file", + input_otio=input_otio, + filepath=filepath, + **adapter_argument_map + ) + + def read_from_string( + self, + input_str, + media_linker_name=media_linker.MediaLinkingPolicy.ForceDefaultLinker, + media_linker_argument_map=None, + hook_function_argument_map={}, + **adapter_argument_map + ): + """Call the read_from_string function on this adapter.""" + + result = self._execute_function( + "read_from_string", + input_str=input_str, + **adapter_argument_map + ) + hook_function_argument_map['adapter_arguments'] = adapter_argument_map + hook_function_argument_map['media_linker_argument_map'] = \ + media_linker_argument_map + + result = hooks.run("post_adapter_read", result, + extra_args=hook_function_argument_map) + + if media_linker_name and ( + media_linker_name != media_linker.MediaLinkingPolicy.DoNotLinkMedia + ): + _with_linked_media_references( + result, + media_linker_name, + media_linker_argument_map + ) + + # @TODO: Should this run *ONLY* if the media linker ran? + result = hooks.run("post_media_linker", result, + extra_args=hook_function_argument_map) + + return result + + def write_to_string( + self, + input_otio, + hook_function_argument_map={}, + **adapter_argument_map + ): + """Call the write_to_string function on this adapter.""" + + hook_function_argument_map['adapter_arguments'] = adapter_argument_map + input_otio = hooks.run("pre_adapter_write", input_otio, + extra_args=hook_function_argument_map) + + return self._execute_function( + "write_to_string", + input_otio=input_otio, + **adapter_argument_map + ) + + def __str__(self): + return ( + "Adapter(" + "{}, " + "{}, " + "{}, " + "{}" + ")".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath), + repr(self.suffixes), + ) + ) + + def __repr__(self): + return ( + "otio.adapter.Adapter(" + "name={}, " + "execution_scope={}, " + "filepath={}, " + "suffixes={}" + ")".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath), + repr(self.suffixes), + ) + ) + + +def _with_linked_media_references( + read_otio, + media_linker_name, + media_linker_argument_map +): + """Link media references in the read_otio if possible. + + Makes changes in place and returns the read_otio structure back. + """ + + if not read_otio or not media_linker.from_name(media_linker_name): + return read_otio + + # not every object the adapter reads has an "each_clip" method, so this + # skips objects without one. + clpfn = getattr(read_otio, "each_clip", None) + if clpfn is None: + return read_otio + + for cl in read_otio.each_clip(): + new_mr = media_linker.linked_media_reference( + cl, + media_linker_name, + # @TODO: should any context get wired in at this point? + media_linker_argument_map + ) + if new_mr is not None: + cl.media_reference = new_mr + + return read_otio + + +# map of attr to look for vs feature name in the adapter plugin +_FEATURE_MAP = { + 'read_from_file': ['read_from_file'], + 'read_from_string': ['read_from_string'], + 'read': ['read_from_file', 'read_from_string'], + 'write_to_file': ['write_to_file'], + 'write_to_string': ['write_to_string'], + 'write': ['write_to_file', 'write_to_string'] +} diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/builtin_adapters.plugin_manifest.json b/pype/vendor/python/python_2/opentimelineio/adapters/builtin_adapters.plugin_manifest.json new file mode 100644 index 0000000000..5e394a67d8 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/builtin_adapters.plugin_manifest.json @@ -0,0 +1,31 @@ +{ + "OTIO_SCHEMA" : "PluginManifest.1", + "adapters": [ + { + "OTIO_SCHEMA": "Adapter.1", + "name": "fcp_xml", + "execution_scope": "in process", + "filepath": "fcp_xml.py", + "suffixes": ["xml"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "otio_json", + "execution_scope" : "in process", + "filepath" : "otio_json.py", + "suffixes" : ["otio"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "cmx_3600", + "execution_scope" : "in process", + "filepath" : "cmx_3600.py", + "suffixes" : ["edl"] + } + ], + "hooks": { + "post_adapter_read" : [], + "post_media_linker" : [], + "pre_adapter_write" : [] + } +} diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/cmx_3600.py b/pype/vendor/python/python_2/opentimelineio/adapters/cmx_3600.py new file mode 100644 index 0000000000..f3275e3929 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/cmx_3600.py @@ -0,0 +1,1306 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO CMX 3600 EDL Adapter""" + +# Note: this adapter is not an ideal model for new adapters, but it works. +# If you want to write your own adapter, please see: +# https://opentimelineio.readthedocs.io/en/latest/tutorials/write-an-adapter.html# + +# TODO: Flesh out Attribute Handler +# TODO: Add line numbers to errors and warnings +# TODO: currently tracks with linked audio/video will lose their linkage when +# read into OTIO. + +import os +import re +import math +import collections + +from .. import ( + exceptions, + schema, + opentime, +) + + +class EDLParseError(exceptions.OTIOError): + pass + + +# regex for parsing the playback speed of an M2 event +SPEED_EFFECT_RE = re.compile( + r"(?P.*?)\s*(?P[0-9\.]*)\s*(?P[0-9:]{11})$" +) + + +# these are all CMX_3600 transition codes +# the wipe is written in regex format because it is W### where the ### is +# a 'wipe code' +# @TODO: not currently read by the transition code +transition_regex_map = { + 'C': 'cut', + 'D': 'dissolve', + r'W\d{3}': 'wipe', + 'KB': 'key_background', + 'K': 'key_foreground', + 'KO': 'key_overlay' +} + +# CMX_3600 supports some shorthand for channel assignments +# We name the actual tracks V and A1,A2,A3,etc. +# This channel_map tells you which track to use for each channel shorthand. +# Channels not listed here are used as track names verbatim. +channel_map = { + 'A': ['A1'], + 'AA': ['A1', 'A2'], + 'B': ['V', 'A1'], + 'A2/V': ['V', 'A2'], + 'AA/V': ['V', 'A1', 'A2'] +} + + +# Currently, the 'style' argument determines +# the comment string for the media reference: +# 'avid': '* FROM CLIP:' (default) +# 'nucoda': '* FROM FILE:' +# When adding a new style, please be sure to add sufficient tests +# to verify both the new and existing styles. +VALID_EDL_STYLES = ['avid', 'nucoda'] + + +class EDLParser(object): + def __init__(self, edl_string, rate=24, ignore_timecode_mismatch=False): + self.timeline = schema.Timeline() + + # Start with no tracks. They will be added as we encounter them. + # This dict maps a track name (e.g "A2" or "V") to an OTIO Track. + self.tracks_by_name = {} + + self.ignore_timecode_mismatch = ignore_timecode_mismatch + + self.parse_edl(edl_string, rate=rate) + + # TODO: Sort the tracks V, then A1,A2,etc. + + def add_clip(self, line, comments, rate=24): + comment_handler = CommentHandler(comments) + clip_handler = ClipHandler(line, comment_handler.handled, rate=rate) + clip = clip_handler.clip + if comment_handler.unhandled: + clip.metadata.setdefault("cmx_3600", {}) + clip.metadata['cmx_3600'].setdefault("comments", []) + clip.metadata['cmx_3600']['comments'] += ( + comment_handler.unhandled + ) + + # Add reel name to metadata + # A reel name of `AX` represents an unknown or auxilary source + # We don't currently track these sources outside of this adapter + # So lets skip adding AX reels as metadata for now, + # as that would dirty json outputs with non-relevant information + if clip_handler.reel and clip_handler.reel != 'AX': + clip.metadata.setdefault("cmx_3600", {}) + clip.metadata['cmx_3600']['reel'] = clip_handler.reel + + # each edit point between two clips is a transition. the default is a + # cut in the edl format the transition codes are for the transition + # into the clip + self.add_transition( + clip_handler, + clip_handler.transition_type, + clip_handler.transition_data + ) + + tracks = self.tracks_for_channel(clip_handler.channel_code) + for track in tracks: + + edl_rate = clip_handler.edl_rate + record_in = opentime.from_timecode( + clip_handler.record_tc_in, + edl_rate + ) + record_out = opentime.from_timecode( + clip_handler.record_tc_out, + edl_rate + ) + + src_duration = clip.duration() + rec_duration = record_out - record_in + if rec_duration != src_duration: + motion = comment_handler.handled.get('motion_effect') + freeze = comment_handler.handled.get('freeze_frame') + if motion is not None or freeze is not None: + # Adjust the clip to match the record duration + clip.source_range = opentime.TimeRange( + start_time=clip.source_range.start_time, + duration=rec_duration + ) + + if freeze is not None: + clip.effects.append(schema.FreezeFrame()) + # XXX remove 'FF' suffix (writing edl will add it back) + if clip.name.endswith(' FF'): + clip.name = clip.name[:-3] + elif motion is not None: + fps = float( + SPEED_EFFECT_RE.match(motion).group("speed") + ) + time_scalar = fps / rate + clip.effects.append( + schema.LinearTimeWarp(time_scalar=time_scalar) + ) + + elif self.ignore_timecode_mismatch: + # Pretend there was no problem by adjusting the record_out. + # Note that we don't actually use record_out after this + # point in the code, since all of the subsequent math uses + # the clip's source_range. Adjusting the record_out is + # just to document what the implications of ignoring the + # mismatch here entails. + record_out = record_in + src_duration + + else: + raise EDLParseError( + "Source and record duration don't match: {} != {}" + " for clip {}".format( + src_duration, + rec_duration, + clip.name + )) + + if track.source_range is None: + zero = opentime.RationalTime(0, edl_rate) + track.source_range = opentime.TimeRange( + start_time=zero - record_in, + duration=zero + ) + + track_end = track.duration() - track.source_range.start_time + if record_in < track_end: + if self.ignore_timecode_mismatch: + # shift it over + record_in = track_end + record_out = record_in + rec_duration + else: + raise EDLParseError( + "Overlapping record in value: {} for clip {}".format( + clip_handler.record_tc_in, + clip.name + )) + + # If the next clip is supposed to start beyond the end of the + # clips we've accumulated so far, then we need to add a Gap + # to fill that space. This can happen when an EDL has record + # timecodes that are sparse (e.g. from a single track of a + # multi-track composition). + if record_in > track_end and len(track) > 0: + gap = schema.Gap() + gap.source_range = opentime.TimeRange( + start_time=opentime.RationalTime(0, edl_rate), + duration=record_in - track_end + ) + track.append(gap) + track.source_range = opentime.TimeRange( + start_time=track.source_range.start_time, + duration=track.source_range.duration + gap.duration() + ) + + track.append(clip) + track.source_range = opentime.TimeRange( + start_time=track.source_range.start_time, + duration=track.source_range.duration + clip.duration() + ) + + def guess_kind_for_track_name(self, name): + if name.startswith("V"): + return schema.TrackKind.Video + if name.startswith("A"): + return schema.TrackKind.Audio + return schema.TrackKind.Video + + def tracks_for_channel(self, channel_code): + # Expand channel shorthand into a list of track names. + if channel_code in channel_map: + track_names = channel_map[channel_code] + else: + track_names = [channel_code] + + # Create any channels we don't already have + for track_name in track_names: + if track_name not in self.tracks_by_name: + track = schema.Track( + name=track_name, + kind=self.guess_kind_for_track_name(track_name) + ) + self.tracks_by_name[track_name] = track + self.timeline.tracks.append(track) + + # Return a list of actual tracks + return [self.tracks_by_name[c] for c in track_names] + + def add_transition(self, clip_handler, transition, data): + if transition not in ['C']: + md = clip_handler.clip.metadata.setdefault("cmx_3600", {}) + md["transition"] = transition + + def parse_edl(self, edl_string, rate=24): + # edl 'events' can be comprised of an indeterminate amount of lines + # we are to translating 'events' to a single clip and transition + # then we add the transition and the clip to all channels the 'event' + # channel code is mapped to the transition given in the 'event' + # precedes the clip + + # remove all blank lines from the edl + edl_lines = [ + l for l in (l.strip() for l in edl_string.splitlines()) if l + ] + + while edl_lines: + # a basic for loop wont work cleanly since we need to look ahead at + # array elements to determine what type of 'event' we are looking + # at + line = edl_lines.pop(0) + + if line.startswith('TITLE:'): + # this is the first line of interest in an edl + # it is required to be in the header + self.timeline.name = line.replace('TITLE:', '').strip() + + elif line.startswith('FCM'): + # this can occur either in the header or before any 'event' + # in both cases we can ignore it since it is meant for tape + # timecode + pass + + elif line.startswith('SPLIT'): + # this is the only comment preceding an 'event' that we care + # about in our context it simply means the next two clips will + # have the same comment data it is for reading purposes only + audio_delay = None + video_delay = None + + if 'AUDIO DELAY' in line: + audio_delay = line.split()[-1].strip() + if 'VIDEO DELAY' in line: + video_delay = line.split()[-1].strip() + if audio_delay and video_delay: + raise EDLParseError( + 'both audio and video delay declared after SPLIT.' + ) + if not (audio_delay or video_delay): + raise EDLParseError( + 'either audio or video delay declared after SPLIT.' + ) + + line_1 = edl_lines.pop(0) + line_2 = edl_lines.pop(0) + + comments = [] + while edl_lines: + if re.match(r'^\D', edl_lines[0]): + comments.append(edl_lines.pop(0)) + else: + break + self.add_clip(line_1, comments, rate=rate) + self.add_clip(line_2, comments, rate=rate) + + elif line[0].isdigit(): + # all 'events' start_time with an edit decision. this is + # denoted by the line beginning with a padded integer 000-999 + comments = [] + while edl_lines: + # any non-numbered lines after an edit decision should be + # treated as 'comments' + # comments are string tags used by the reader to get extra + # information not able to be found in the restricted edl + # format + if re.match(r'^\D', edl_lines[0]): + comments.append(edl_lines.pop(0)) + else: + break + + self.add_clip(line, comments, rate=rate) + + else: + raise EDLParseError('Unknown event type') + + for track in self.timeline.tracks: + # if the source_range is the same as the available_range + # then we don't need to set it at all. + if track.source_range == track.available_range(): + track.source_range = None + + +class ClipHandler(object): + + def __init__(self, line, comment_data, rate=24): + self.clip_num = None + self.reel = None + self.channel_code = None + self.edl_rate = rate + self.transition_id = None + self.transition_data = None + self.source_tc_in = None + self.source_tc_out = None + self.record_tc_in = None + self.record_tc_out = None + + self.parse(line) + self.clip = self.make_clip(comment_data) + + def make_clip(self, comment_data): + clip = schema.Clip() + clip.name = str(self.clip_num) + + # BLACK/BL and BARS are called out as "Special Source Identifiers" in + # the documents referenced here: + # https://github.com/PixarAnimationStudios/OpenTimelineIO#cmx3600-edl + if self.reel in ['BL', 'BLACK']: + clip.media_reference = schema.GeneratorReference() + # TODO: Replace with enum, once one exists + clip.media_reference.generator_kind = 'black' + elif self.reel == 'BARS': + clip.media_reference = schema.GeneratorReference() + # TODO: Replace with enum, once one exists + clip.media_reference.generator_kind = 'SMPTEBars' + elif 'media_reference' in comment_data: + clip.media_reference = schema.ExternalReference() + clip.media_reference.target_url = comment_data[ + 'media_reference' + ] + else: + clip.media_reference = schema.MissingReference() + + # this could currently break without a 'FROM CLIP' comment. + # Without that there is no 'media_reference' Do we have a default + # clip name? + if 'clip_name' in comment_data: + clip.name = comment_data["clip_name"] + elif ( + clip.media_reference and + hasattr(clip.media_reference, 'target_url') and + clip.media_reference.target_url is not None + ): + clip.name = os.path.splitext( + os.path.basename(clip.media_reference.target_url) + )[0] + + asc_sop = comment_data.get('asc_sop', None) + asc_sat = comment_data.get('asc_sat', None) + if asc_sop or asc_sat: + slope = (1, 1, 1) + offset = (0, 0, 0) + power = (1, 1, 1) + sat = 1.0 + + if asc_sop: + triple = r'([-+]?[\d.]+) ([-+]?[\d.]+) ([-+]?[\d.]+)' + m = re.match( + r'\(' + + triple + + r'\)\s*\(' + + triple + r'\)\s*\(' + + triple + r'\)', + asc_sop + ) + if m: + floats = [float(g) for g in m.groups()] + slope = [floats[0], floats[1], floats[2]] + offset = [floats[3], floats[4], floats[5]] + power = [floats[6], floats[7], floats[8]] + else: + raise EDLParseError( + 'Invalid ASC_SOP found: {}'.format(asc_sop)) + + if asc_sat: + sat = float(asc_sat) + + clip.metadata['cdl'] = { + 'asc_sat': sat, + 'asc_sop': { + 'slope': slope, + 'offset': offset, + 'power': power + } + } + + if 'locator' in comment_data: + # An example EDL locator line looks like this: + # * LOC: 01:00:01:14 RED ANIM FIX NEEDED + # We get the part after "LOC: " as the comment_data entry + # Given the fixed-width nature of these, we could be more + # strict about the field widths, but there are many + # variations of EDL, so if we are lenient then maybe we + # can handle more of them? Only real-world testing will + # determine this for sure... + m = re.match( + r'(\d\d:\d\d:\d\d:\d\d)\s+(\w*)\s+(.*)', + comment_data["locator"] + ) + if m: + marker = schema.Marker() + marker.marked_range = opentime.TimeRange( + start_time=opentime.from_timecode( + m.group(1), + self.edl_rate + ), + duration=opentime.RationalTime() + ) + + # always write the source value into metadata, in case it + # is not a valid enum somehow. + color_parsed_from_file = m.group(2) + + marker.metadata = { + "cmx_3600": { + "color": color_parsed_from_file + } + } + + # @TODO: if it is a valid + if hasattr( + schema.MarkerColor, + color_parsed_from_file.upper() + ): + marker.color = color_parsed_from_file.upper() + else: + marker.color = schema.MarkerColor.RED + + marker.name = m.group(3) + clip.markers.append(marker) + else: + # TODO: Should we report this as a warning somehow? + pass + + clip.source_range = opentime.range_from_start_end_time( + opentime.from_timecode(self.source_tc_in, self.edl_rate), + opentime.from_timecode(self.source_tc_out, self.edl_rate) + ) + + return clip + + def parse(self, line): + fields = tuple(e.strip() for e in line.split() if e.strip()) + field_count = len(fields) + + if field_count == 9: + # has transition data + # this is for edits with timing or other needed info + # transition data for D and W*** transitions is a n integer that + # denotes frame count + # i haven't figured out how the key transitions (K, KB, KO) work + ( + self.clip_num, + self.reel, + self.channel_code, + self.transition_type, + self.transition_data, + self.source_tc_in, + self.source_tc_out, + self.record_tc_in, + self.record_tc_out + ) = fields + + elif field_count == 8: + # no transition data + # this is for basic cuts + ( + self.clip_num, + self.reel, + self.channel_code, + self.transition_type, + self.source_tc_in, + self.source_tc_out, + self.record_tc_in, + self.record_tc_out + ) = fields + + else: + raise EDLParseError( + 'incorrect number of fields [{0}] in form statement: {1}' + ''.format(field_count, line)) + + # Frame numbers (not just timecode) are ok + for prop in [ + 'source_tc_in', + 'source_tc_out', + 'record_tc_in', + 'record_tc_out' + ]: + if ':' not in getattr(self, prop): + setattr( + self, + prop, + opentime.to_timecode( + opentime.from_frames( + int(getattr(self, prop)), + self.edl_rate + ), + self.edl_rate + ) + ) + + +class CommentHandler(object): + # this is the for that all comment 'id' tags take + regex_template = r'\*?\s*{id}:?\s*(?P.*)' + + # this should be a map of all known comments that we can read + # 'FROM CLIP' or 'FROM FILE' is a required comment to link media + # An exception is raised if both 'FROM CLIP' and 'FROM FILE' are found + # needs to be ordered so that FROM CLIP NAME gets matched before FROM CLIP + comment_id_map = collections.OrderedDict([ + ('FROM CLIP NAME', 'clip_name'), + ('FROM CLIP', 'media_reference'), + ('FROM FILE', 'media_reference'), + ('LOC', 'locator'), + ('ASC_SOP', 'asc_sop'), + ('ASC_SAT', 'asc_sat'), + ('M2', 'motion_effect'), + ('\\* FREEZE FRAME', 'freeze_frame'), + ]) + + def __init__(self, comments): + self.handled = {} + self.unhandled = [] + for comment in comments: + self.parse(comment) + + def parse(self, comment): + for comment_id, comment_type in self.comment_id_map.items(): + regex = self.regex_template.format(id=comment_id) + match = re.match(regex, comment) + if match: + self.handled[comment_type] = match.group( + 'comment_body' + ).strip() + break + else: + stripped = comment.lstrip('*').strip() + if stripped: + self.unhandled.append(stripped) + + +def _expand_transitions(timeline): + """Convert clips with metadata/transition == 'D' into OTIO transitions.""" + + tracks = timeline.tracks + remove_list = [] + replace_list = [] + append_list = [] + for track in tracks: + track_iter = iter(track) + # avid inserts an extra clip for the source + prev_prev = None + prev = None + clip = next(track_iter, None) + next_clip = next(track_iter, None) + while clip is not None: + transition_type = clip.metadata.get('cmx_3600', {}).get( + 'transition', + 'C' + ) + + if transition_type == 'C': + # nothing to do, continue to the next iteration of the loop + prev_prev = prev + prev = clip + clip = next_clip + next_clip = next(track_iter, None) + continue + if transition_type not in ['D']: + raise EDLParseError( + "Transition type '{}' not supported by the CMX EDL reader " + "currently.".format(transition_type) + ) + + transition_duration = clip.duration() + + # EDL doesn't have enough data to know where the cut point was, so + # this arbitrarily puts it in the middle of the transition + pre_cut = math.floor(transition_duration.value / 2) + post_cut = transition_duration.value - pre_cut + mid_tran_cut_pre_duration = opentime.RationalTime( + pre_cut, + transition_duration.rate + ) + mid_tran_cut_post_duration = opentime.RationalTime( + post_cut, + transition_duration.rate + ) + + # expand the previous + expansion_clip = None + if prev and not prev_prev: + expansion_clip = prev + elif prev_prev: + expansion_clip = prev_prev + if prev: + remove_list.append((track, prev)) + + sr = expansion_clip.source_range + expansion_clip.source_range = opentime.TimeRange( + start_time=sr.start_time, + duration=sr.duration + mid_tran_cut_pre_duration + ) + + # rebuild the clip as a transition + new_trx = schema.Transition( + name=clip.name, + # only supported type at the moment + transition_type=schema.TransitionTypes.SMPTE_Dissolve, + metadata=clip.metadata + ) + new_trx.in_offset = mid_tran_cut_pre_duration + new_trx.out_offset = mid_tran_cut_post_duration + + # in from to + replace_list.append((track, clip, new_trx)) + + # expand the next_clip + if next_clip: + next_clip.source_range = opentime.TimeRange( + next_clip.source_range.start_time - mid_tran_cut_post_duration, + next_clip.source_range.duration + mid_tran_cut_post_duration + ) + else: + fill = schema.Gap( + source_range=opentime.TimeRange( + duration=mid_tran_cut_post_duration, + start_time=opentime.RationalTime( + 0, + transition_duration.rate + ) + ) + ) + append_list.append((track, fill)) + + prev = clip + clip = next_clip + next_clip = next(track_iter, None) + + for (track, from_clip, to_transition) in replace_list: + track[track.index(from_clip)] = to_transition + + for (track, clip_to_remove) in list(set(remove_list)): + # if clip_to_remove in track: + track.remove(clip_to_remove) + + for (track, clip) in append_list: + track.append(clip) + + return timeline + + +def read_from_string(input_str, rate=24, ignore_timecode_mismatch=False): + """Reads a CMX Edit Decision List (EDL) from a string. + Since EDLs don't contain metadata specifying the rate they are meant + for, you may need to specify the rate parameter (default is 24). + By default, read_from_string will throw an exception if it discovers + invalid timecode in the EDL. For example, if a clip's record timecode + overlaps with the previous cut. Since this is a common mistake in + many EDLs, you can specify ignore_timecode_mismatch=True, which will + supress these errors and attempt to guess at the correct record + timecode based on the source timecode and adjacent cuts. + For best results, you may wish to do something like this: + + Example: + >>> try: + ... timeline = otio.adapters.read_from_string("mymovie.edl", rate=30) + ... except EDLParseError: + ... print('Log a warning here') + ... try: + ... timeline = otio.adapters.read_from_string( + ... "mymovie.edl", + ... rate=30, + ... ignore_timecode_mismatch=True) + ... except EDLParseError: + ... print('Log an error here') + """ + parser = EDLParser( + input_str, + rate=float(rate), + ignore_timecode_mismatch=ignore_timecode_mismatch + ) + result = parser.timeline + result = _expand_transitions(result) + return result + + +def write_to_string(input_otio, rate=None, style='avid', reelname_len=8): + # TODO: We should have convenience functions in Timeline for this? + # also only works for a single video track at the moment + + video_tracks = [t for t in input_otio.tracks + if t.kind == schema.TrackKind.Video] + audio_tracks = [t for t in input_otio.tracks + if t.kind == schema.TrackKind.Audio] + + if len(video_tracks) != 1: + raise exceptions.NotSupportedError( + "Only a single video track is supported, got: {}".format( + len(video_tracks) + ) + ) + + if len(audio_tracks) > 2: + raise exceptions.NotSupportedError( + "No more than 2 audio tracks are supported." + ) + # if audio_tracks: + # raise exceptions.NotSupportedError( + # "No audio tracks are currently supported." + # ) + + # TODO: We should try to detect the frame rate and output an + # appropriate "FCM: NON-DROP FRAME" etc here. + + writer = EDLWriter( + tracks=input_otio.tracks, + # Assume all rates are the same as the 1st track's + rate=rate or input_otio.tracks[0].duration().rate, + style=style, + reelname_len=reelname_len + ) + + return writer.get_content_for_track_at_index(0, title=input_otio.name) + + +class EDLWriter(object): + def __init__(self, tracks, rate, style, reelname_len=8): + self._tracks = tracks + self._rate = rate + self._style = style + self._reelname_len = reelname_len + + if style not in VALID_EDL_STYLES: + raise exceptions.NotSupportedError( + "The EDL style '{}' is not supported.".format( + style + ) + ) + + def get_content_for_track_at_index(self, idx, title): + track = self._tracks[idx] + + # Add a gap if the last child is a transition. + if isinstance(track[-1], schema.Transition): + gap = schema.Gap( + source_range=opentime.TimeRange( + start_time=track[-1].duration(), + duration=opentime.RationalTime(0.0, self._rate) + ) + ) + track.append(gap) + + # Note: Transitions in EDLs are unconventionally represented. + # + # Where a transition might normally be visualized like: + # |---57.0 Trans 43.0----| + # |------Clip1 102.0------|----------Clip2 143.0----------|Clip3 24.0| + # + # In an EDL it can be thought of more like this: + # |---0.0 Trans 100.0----| + # |Clip1 45.0|----------------Clip2 200.0-----------------|Clip3 24.0| + + # Adjust cut points to match EDL event representation. + for idx, child in enumerate(track): + if isinstance(child, schema.Transition): + if idx != 0: + # Shorten the a-side + sr = track[idx - 1].source_range + track[idx - 1].source_range = opentime.TimeRange( + start_time=sr.start_time, + duration=sr.duration - child.in_offset + ) + + # Lengthen the b-side + sr = track[idx + 1].source_range + track[idx + 1].source_range = opentime.TimeRange( + start_time=sr.start_time - child.in_offset, + duration=sr.duration + child.in_offset + ) + + # Just clean up the transition for goodness sake + in_offset = child.in_offset + child.in_offset = opentime.RationalTime(0.0, self._rate) + child.out_offset += in_offset + + # Group events into either simple clip/a-side or transition and b-side + # to match EDL edit/event representation and edit numbers. + events = [] + for idx, child in enumerate(track): + if isinstance(child, schema.Transition): + # Transition will be captured in subsequent iteration. + continue + + prv = track[idx - 1] if idx > 0 else None + + if isinstance(prv, schema.Transition): + events.append( + DissolveEvent( + events[-1] if len(events) else None, + prv, + child, + self._tracks, + track.kind, + self._rate, + self._style, + self._reelname_len + ) + ) + elif isinstance(child, schema.Clip): + events.append( + Event( + child, + self._tracks, + track.kind, + self._rate, + self._style, + self._reelname_len + ) + ) + elif isinstance(child, schema.Gap): + # Gaps are represented as missing record timecode, no event + # needed. + pass + + content = "TITLE: {}\n\n".format(title) if title else '' + + # Convert each event/dissolve-event into plain text. + for idx, event in enumerate(events): + event.edit_number = idx + 1 + content += event.to_edl_format() + '\n' + + return content + + +def _supported_timing_effects(clip): + return [ + fx for fx in clip.effects + if isinstance(fx, schema.LinearTimeWarp) + ] + + +def _relevant_timing_effect(clip): + # check to see if there is more than one timing effect + effects = _supported_timing_effects(clip) + + if effects != clip.effects: + for thing in clip.effects: + if thing not in effects and isinstance(thing, schema.TimeEffect): + raise exceptions.NotSupportedError( + "Clip contains timing effects not supported by the EDL" + " adapter.\nClip: {}".format(str(clip))) + + timing_effect = None + if effects: + timing_effect = effects[0] + if len(effects) > 1: + raise exceptions.NotSupportedError( + "EDL Adapter only allows one timing effect / clip." + ) + + return timing_effect + + +class Event(object): + def __init__( + self, + clip, + tracks, + kind, + rate, + style, + reelname_len + ): + + line = EventLine(kind, rate, reel=_reel_from_clip(clip, reelname_len)) + line.source_in = clip.source_range.start_time + line.source_out = clip.source_range.end_time_exclusive() + + timing_effect = _relevant_timing_effect(clip) + + if timing_effect: + if timing_effect.effect_name == "FreezeFrame": + line.source_out = line.source_in + opentime.RationalTime( + 1, + line.source_in.rate + ) + elif timing_effect.effect_name == "LinearTimeWarp": + value = clip.trimmed_range().duration.value / timing_effect.time_scalar + line.source_out = ( + line.source_in + opentime.RationalTime(value, rate)) + + range_in_timeline = clip.transformed_time_range( + clip.trimmed_range(), + tracks + ) + line.record_in = range_in_timeline.start_time + line.record_out = range_in_timeline.end_time_exclusive() + self.line = line + + self.comments = _generate_comment_lines( + clip=clip, + style=style, + edl_rate=rate, + reelname_len=reelname_len, + from_or_to='FROM' + ) + + self.clip = clip + self.source_out = line.source_out + self.record_out = line.record_out + self.reel = line.reel + + def __str__(self): + return '{type}({name})'.format( + type=self.clip.schema_name(), + name=self.clip.name + ) + + def to_edl_format(self): + """ + Example output: + 002 AX V C 00:00:00:00 00:00:00:05 00:00:00:05 00:00:00:10 + * FROM CLIP NAME: test clip2 + * FROM FILE: S:\\var\\tmp\\test.exr + + """ + lines = [self.line.to_edl_format(self.edit_number)] + lines += self.comments if len(self.comments) else [] + + return "\n".join(lines) + + +class DissolveEvent(object): + + def __init__( + self, + a_side_event, + transition, + b_side_clip, + tracks, + kind, + rate, + style, + reelname_len + ): + # Note: We don't make the A-Side event line here as it is represented + # by its own event (edit number). + + cut_line = EventLine(kind, rate) + + if a_side_event: + cut_line.reel = a_side_event.reel + cut_line.source_in = a_side_event.source_out + cut_line.source_out = a_side_event.source_out + cut_line.record_in = a_side_event.record_out + cut_line.record_out = a_side_event.record_out + + self.from_comments = _generate_comment_lines( + clip=a_side_event.clip, + style=style, + edl_rate=rate, + reelname_len=reelname_len, + from_or_to='FROM' + ) + else: + cut_line.reel = 'BL' + cut_line.source_in = opentime.RationalTime(0.0, rate) + cut_line.source_out = opentime.RationalTime(0.0, rate) + cut_line.record_in = opentime.RationalTime(0.0, rate) + cut_line.record_out = opentime.RationalTime(0.0, rate) + + self.cut_line = cut_line + + dslve_line = EventLine( + kind, + rate, + reel=_reel_from_clip(b_side_clip, reelname_len) + ) + dslve_line.source_in = b_side_clip.source_range.start_time + dslve_line.source_out = b_side_clip.source_range.end_time_exclusive() + range_in_timeline = b_side_clip.transformed_time_range( + b_side_clip.trimmed_range(), + tracks + ) + dslve_line.record_in = range_in_timeline.start_time + dslve_line.record_out = range_in_timeline.end_time_exclusive() + dslve_line.dissolve_length = transition.out_offset + self.dissolve_line = dslve_line + + self.to_comments = _generate_comment_lines( + clip=b_side_clip, + style=style, + edl_rate=rate, + reelname_len=reelname_len, + from_or_to='TO' + ) + + self.a_side_event = a_side_event + self.transition = transition + self.b_side_clip = b_side_clip + + # Expose so that any subsequent dissolves can borrow their values. + self.clip = b_side_clip + self.source_out = dslve_line.source_out + self.record_out = dslve_line.record_out + self.reel = dslve_line.reel + + def __str__(self): + a_side = self.a_side_event + return '{a_type}({a_name}) -> {b_type}({b_name})'.format( + a_type=a_side.clip.schema_name() if a_side else '', + a_name=a_side.clip.name if a_side else '', + b_type=self.b_side_clip.schema_name(), + b_name=self.b_side_clip.name + ) + + def to_edl_format(self): + """ + Example output: + + Cross dissolve... + 002 Clip1 V C 00:00:07:08 00:00:07:08 00:00:01:21 00:00:01:21 + 002 Clip2 V D 100 00:00:09:07 00:00:17:15 00:00:01:21 00:00:10:05 + * FROM CLIP NAME: Clip1 + * FROM CLIP: /var/tmp/clip1.001.exr + * TO CLIP NAME: Clip2 + * TO CLIP: /var/tmp/clip2.001.exr + + Fade in... + 001 BL V C 00:00:00:00 00:00:00:00 00:00:00:00 00:00:00:00 + 001 My_Clip V D 012 00:00:02:02 00:00:03:04 00:00:00:00 00:00:01:02 + * TO CLIP NAME: My Clip + * TO FILE: /var/tmp/clip.001.exr + + Fade out... + 002 My_Clip V C 00:00:01:12 00:00:01:12 00:00:00:12 00:00:00:12 + 002 BL V D 012 00:00:00:00 00:00:00:12 00:00:00:12 00:00:01:00 + * FROM CLIP NAME: My Clip + * FROM FILE: /var/tmp/clip.001.exr + """ + + lines = [ + self.cut_line.to_edl_format(self.edit_number), + self.dissolve_line.to_edl_format(self.edit_number) + ] + lines += self.from_comments if hasattr(self, 'from_comments') else [] + lines += self.to_comments if len(self.to_comments) else [] + + return "\n".join(lines) + + +class EventLine(object): + def __init__(self, kind, rate, reel='AX'): + self.reel = reel + self._kind = 'V' if kind == schema.TrackKind.Video else 'A' + self._rate = rate + + self.source_in = opentime.RationalTime(0.0, rate=rate) + self.source_out = opentime.RationalTime(0.0, rate=rate) + self.record_in = opentime.RationalTime(0.0, rate=rate) + self.record_out = opentime.RationalTime(0.0, rate=rate) + + self.dissolve_length = opentime.RationalTime(0.0, rate) + + def to_edl_format(self, edit_number): + ser = { + 'edit': edit_number, + 'reel': self.reel, + 'kind': self._kind, + 'src_in': opentime.to_timecode(self.source_in, self._rate), + 'src_out': opentime.to_timecode(self.source_out, self._rate), + 'rec_in': opentime.to_timecode(self.record_in, self._rate), + 'rec_out': opentime.to_timecode(self.record_out, self._rate), + 'diss': int( + opentime.to_frames(self.dissolve_length, self._rate) + ), + } + + if self.is_dissolve(): + return "{edit:03d} {reel:8} {kind:5} D {diss:03d} " \ + "{src_in} {src_out} {rec_in} {rec_out}".format(**ser) + else: + return "{edit:03d} {reel:8} {kind:5} C " \ + "{src_in} {src_out} {rec_in} {rec_out}".format(**ser) + + def is_dissolve(self): + return self.dissolve_length.value > 0 + + +def _generate_comment_lines( + clip, + style, + edl_rate, + reelname_len, + from_or_to='FROM' +): + lines = [] + url = None + + if not clip or isinstance(clip, schema.Gap): + return [] + + suffix = '' + timing_effect = _relevant_timing_effect(clip) + if timing_effect and timing_effect.effect_name == 'FreezeFrame': + suffix = ' FF' + + if clip.media_reference: + if hasattr(clip.media_reference, 'target_url'): + url = clip.media_reference.target_url + + else: + url = clip.name + + if from_or_to not in ['FROM', 'TO']: + raise exceptions.NotSupportedError( + "The clip FROM or TO value '{}' is not supported.".format( + from_or_to + ) + ) + + if timing_effect and isinstance(timing_effect, schema.LinearTimeWarp): + lines.append( + 'M2 {}\t\t{}\t\t\t{}'.format( + clip.name, + timing_effect.time_scalar * edl_rate, + opentime.to_timecode( + clip.trimmed_range().start_time, + edl_rate + ) + ) + ) + + if clip.name: + # Avid Media Composer outputs two spaces before the + # clip name so we match that. + lines.append( + "* {from_or_to} CLIP NAME: {name}{suffix}".format( + from_or_to=from_or_to, + name=clip.name, + suffix=suffix + ) + ) + if timing_effect and timing_effect.effect_name == "FreezeFrame": + lines.append('* * FREEZE FRAME') + if url and style == 'avid': + lines.append("* {from_or_to} CLIP: {url}".format( + from_or_to=from_or_to, + url=url + )) + if url and style == 'nucoda': + lines.append("* {from_or_to} FILE: {url}".format( + from_or_to=from_or_to, + url=url + )) + + if reelname_len and not clip.metadata.get('cmx_3600', {}).get('reel'): + lines.append("* OTIO TRUNCATED REEL NAME FROM: {url}".format( + url=os.path.basename(_flip_windows_slashes(url or clip.name)) + )) + + cdl = clip.metadata.get('cdl') + if cdl: + asc_sop = cdl.get('asc_sop') + asc_sat = cdl.get('asc_sat') + if asc_sop: + lines.append( + "*ASC_SOP ({} {} {}) ({} {} {}) ({} {} {})".format( + asc_sop['slope'][0], + asc_sop['slope'][1], + asc_sop['slope'][2], + asc_sop['offset'][0], + asc_sop['offset'][1], + asc_sop['offset'][2], + asc_sop['power'][0], + asc_sop['power'][1], + asc_sop['power'][2] + )) + if asc_sat: + lines.append("*ASC_SAT {}".format( + asc_sat + )) + + # Output any markers on this clip + for marker in clip.markers: + timecode = opentime.to_timecode( + marker.marked_range.start_time, + edl_rate + ) + + color = marker.color + meta = marker.metadata.get("cmx_3600") + if not color and meta and meta.get("color"): + color = meta.get("color").upper() + comment = (marker.name or '').upper() + lines.append("* LOC: {} {:7} {}".format(timecode, color, comment)) + + # If we are carrying any unhandled CMX 3600 comments on this clip + # then output them blindly. + extra_comments = clip.metadata.get('cmx_3600', {}).get('comments', []) + for comment in extra_comments: + lines.append("* {}".format(comment)) + + return lines + + +def _flip_windows_slashes(path): + return re.sub(r'\\', '/', path) + + +def _reel_from_clip(clip, reelname_len): + if isinstance(clip, schema.Gap): + return 'BL' + + elif clip.metadata.get('cmx_3600', {}).get('reel'): + return clip.metadata.get('cmx_3600').get('reel') + + _reel = clip.name or 'AX' + + if isinstance(clip.media_reference, schema.ExternalReference): + _reel = clip.media_reference.name or os.path.basename( + clip.media_reference.target_url + ) + + # Flip Windows slashes + _reel = os.path.basename(_flip_windows_slashes(_reel)) + + # Strip extension + reel = re.sub(r'([.][a-zA-Z]+)$', '', _reel) + + if reelname_len: + # Remove non valid characters + reel = re.sub(r'[^ a-zA-Z0-9]+', '', reel) + + if len(reel) > reelname_len: + reel = reel[:reelname_len] + + elif len(reel) < reelname_len: + reel += ' ' * (reelname_len - len(reel)) + + return reel diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/fcp_xml.py b/pype/vendor/python/python_2/opentimelineio/adapters/fcp_xml.py new file mode 100644 index 0000000000..48f684cc36 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/fcp_xml.py @@ -0,0 +1,1941 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO Final Cut Pro 7 XML Adapter.""" + +import collections +import functools +import itertools +import math +import os +import re +from xml.etree import cElementTree +from xml.dom import minidom + +# urlparse's name changes in Python 3 +try: + # Python 2.7 + import urlparse as urllib_parse +except ImportError: + # Python 3 + import urllib.parse as urllib_parse + +# Same with the ABC classes from collections +try: + # Python 3 + from collections.abc import Mapping +except ImportError: + # Python 2.7 + from collections import Mapping + +from opentimelineio import ( + core, + opentime, + schema, +) + +# namespace to use for metadata +META_NAMESPACE = 'fcp_xml' + +# Regex to match identifiers like clipitem-22 +ID_RE = re.compile(r"^(?P[a-zA-Z]*)-(?P\d*)$") + + +# --------- +# utilities +# --------- + + +class _Context(Mapping): + """ + An inherited value context. + + In FCP XML there is a concept of inheritance down the element heirarchy. + For instance, a ``clip`` element may not specify the ``rate`` locally, but + instead inherit it from the parent ``track`` element. + + This object models that as a stack of elements. When a value needs to be + queried from the context, it will be gathered by walking from the top of + the stack until the value is found. + + For example, to find the ``rate`` element as an immediate child most + appropriate to the current context, you would do something like:: + ``my_current_context["./rate"]`` + + This object can be thought of as immutable. You get a new context when you + push an element. This prevents inadvertant tampering with parent contexts + that may be used at levels above. + + This DOES NOT support ``id`` attribute dereferencing, please make sure to + do that prior to using this structure. + + .. seealso:: https://developer.apple.com/library/archive/documentation\ + /AppleApplications/Reference/FinalCutPro_XML/Basics/Basics.html#\ + //apple_ref/doc/uid/TP30001154-TPXREF102 + """ + + def __init__(self, element=None, parent_elements=None): + if parent_elements is not None: + self.elements = parent_elements[:] + else: + self.elements = [] + + if element is not None: + self.elements.append(element) + + def _all_keys(self): + """ + Returns a set of all the keys available in the context stack. + """ + return set( + itertools.chain.fromiterable(e.keys() for e in self.elements) + ) + + def __getitem__(self, key): + # Walk down the contexts until the item is found + for element in reversed(self.elements): + found_element = element.find(key) + if found_element is not None: + return found_element + + raise KeyError(key) + + def __iter__(self): + # This is unlikely to be used, so we'll do it the expensive way + return iter(self._all_keys) + + def __len__(self): + # This is unlikely to be used, so we'll do it the expensive way + return len(self._all_keys) + + def context_pushing_element(self, element): + """ + Pushes an element to the top of the stack. + + :param element: Element to push to the stack. + :return: The new context with the provided element pushed to the top + of the stack. + :raises: :class:`ValueError` if the element is already in the stack. + """ + for context_element in self.elements: + if context_element == element: + raise ValueError( + "element {} already in context".format(element) + ) + + return _Context(element, self.elements) + + +def _url_to_path(url): + parsed = urllib_parse.urlparse(url) + return parsed.path + + +def _bool_value(element): + """ + Given an xml element, returns the tag text converted to a bool. + + :param element: The element to fetch the value from. + + :return: A boolean. + """ + return (element.text.lower() == "true") + + +def _element_identification_string(element): + """ + Gets a string that will hopefully help in identifing an element when there + is an error. + """ + info_string = "tag: {}".format(element.tag) + try: + elem_id = element.attrib["id"] + info_string += " id: {}".format(elem_id) + except KeyError: + pass + + return info_string + + +def _name_from_element(element): + """ + Fetches the name from the ``name`` element child of the provided element. + If no element exists, returns ``None``. + + :param element: The element to find the name for. + + :return: The name string or ``None`` + """ + name_elem = element.find("./name") + if name_elem is not None: + return name_elem.text + + return None + + +def _rate_for_element(element): + """ + Takes an FCP rate element and returns a rate to use with otio. + + :param element: An FCP rate element. + + :return: The float rate. + """ + # rate is encoded as a timebase (int) which can be drop-frame + base = float(element.find("./timebase").text) + if _bool_value(element.find("./ntsc")): + base *= 1000.0 / 1001 + + return base + + +def _rate_from_context(context): + """ + Given the context object, gets the appropriate rate. + + :param context: The :class:`_Context` instance to find the rate in. + + :return: The rate value or ``None`` if no rate is available in the context. + """ + try: + rate_element = context["./rate"] + except KeyError: + return None + + return _rate_for_element(rate_element) + + +def _time_from_timecode_element(tc_element, context=None): + """ + Given a timecode xml element, returns the time that represents. + + .. todo:: Non Drop-Frame timecode is not yet supported by OTIO. + + :param tc_element: The ``timecode`` element. + :param context: The context dict under which this timecode is being gotten. + + :return: The :class:`opentime.RationalTime` representation of the + timecode. + """ + if context is not None: + local_context = context.context_pushing_element(tc_element) + else: + local_context = _Context(tc_element) + + # Resolve the rate + rate = _rate_from_context(local_context) + + # Try using the display format and frame number + frame = tc_element.find("./frame") + + # Use frame number, if available + if frame is not None: + frame_num = int(frame.text) + return opentime.RationalTime(frame_num, rate) + + # If a TC string is provided, parse rate from it + tc_string_element = tc_element.find("./string") + if tc_string_element is None: + raise ValueError("Timecode element missing required elements") + + tc_string = tc_string_element.text + + return opentime.from_timecode(tc_string, rate) + + +def _track_kind_from_element(media_element): + """ + Given an FCP XML media sub-element, returns an appropriate + :class:`schema.TrackKind` value corresponding to that media type. + + :param media_element: An XML element that is a child of the ``media`` tag. + + :return: The corresponding :class`schema.TrackKind` value. + :raises: :class:`ValueError` When the media type is unsupported. + """ + element_tag = media_element.tag.lower() + if element_tag == "audio": + return schema.TrackKind.Audio + elif element_tag == "video": + return schema.TrackKind.Video + + raise ValueError("Unsupported media kind: {}".format(media_element.tag)) + + +def _is_primary_audio_channel(track): + """ + Determines whether or not this is the "primary" audio track. + + audio may be structured in stereo where each channel occupies a separate + track. This importer keeps stereo pairs ganged together as a single track. + + :param track: An XML track element. + + :return: A boolean ``True`` if this is the first track. + """ + exploded_index = track.attrib.get('currentExplodedTrackIndex', '0') + exploded_count = track.attrib.get('totalExplodedTrackCount', '1') + + return (exploded_index == '0' or exploded_count == '1') + + +def _transition_cut_point(transition_item, context): + """ + Returns the end time at which the transition progresses from one clip to + the next. + + :param transition_item: The XML element for the transition. + :param context: The context dictionary applying to this transition. + + :return: The :class:`opentime.RationalTime` the transition cuts at. + """ + alignment = transition_item.find('./alignment').text + start = int(transition_item.find('./start').text) + end = int(transition_item.find('./end').text) + + # start/end time is in the parent context's rate + local_context = context.context_pushing_element(transition_item) + rate = _rate_from_context(local_context) + + if alignment in ('end', 'end-black'): + value = end + elif alignment in ('start', 'start-black'): + value = start + elif alignment in ('center',): + value = int((start + end) / 2) + else: + value = int((start + end) / 2) + + return opentime.RationalTime(value, rate) + + +def _xml_tree_to_dict(node, ignore_tags=None, omit_timing=True): + """ + Translates the tree under a provided node mapping to a dictionary/list + representation. XML tag attributes are placed in the dictionary with an + ``@`` prefix. + + .. note:: In addition to the provided ignore tags, this filters a subset of + timing metadata such as ``frame`` and ``string`` elements within timecode + elements. + + .. warning:: This scheme does not allow for leaf elements to have + attributes. for the moment this doesn't seem to be an issue. + + :param node: The root xml element to express childeren of in the + dictionary. + :param ignore_tags: A collection of tagnames to skip when converting. + :param omit_timing: If ``True``, omits timing-specific tags. + + :return: The dictionary representation. + """ + if node.tag == "timecode": + additional_ignore_tags = {"frame", "string"} + else: + additional_ignore_tags = tuple() + + out_dict = collections.OrderedDict() + + # Handle the attributes + out_dict.update( + collections.OrderedDict( + ("@{}".format(k), v) for k, v in node.attrib.items() + ) + ) + + # Now traverse the child tags + encountered_tags = set() + list_tags = set() + for info_node in node: + # Skip tags we were asked to omit + node_tag = info_node.tag + if ignore_tags and node_tag in ignore_tags: + continue + + # Skip some special case tags related to timing information + if node_tag in additional_ignore_tags: + continue + + # If there are children, make this a sub-dictionary by recursing + if len(info_node): + node_value = _xml_tree_to_dict(info_node) + else: + node_value = info_node.text + + # If we've seen this node before, then treat it as a list + if node_tag in list_tags: + # We've established that this tag is a list, append to that + out_dict[node_tag].append(node_value) + elif node_tag in encountered_tags: + # This appears to be a list we didn't know about, convert + out_dict[node_tag] = [ + out_dict[node_tag], node_value + ] + list_tags.add(node_tag) + else: + # Store the value + out_dict[node_tag] = node_value + encountered_tags.add(node_tag) + + return out_dict + + +def _dict_to_xml_tree(data_dict, tag): + """ + Given a dictionary, returns an element tree storing the data. This is the + inverse of :func:`_xml_tree_to_dict`. + + Any key/value pairs in the dictionary heirarchy where the key is prefixed + with ``@`` will be treated as attributes on the containing element. + + .. note:: This will automatically omit some kinds of metadata it should + be up to the xml building functions to manage (such as timecode and id). + + :param data_dict: The dictionary to turn into an XML tree. + :param tag: The tag name to use for the top-level element. + + :return: The top element for the dictionary + """ + top_attributes = collections.OrderedDict( + (k[1:], v) for k, v in data_dict.items() + if k != "@id" and k.startswith("@") + ) + top_element = cElementTree.Element(tag, **top_attributes) + + def elements_for_value(python_value, element_tag): + """ Creates a list of appropriate XML elements given a value. """ + if isinstance(python_value, dict): + element = _dict_to_xml_tree(python_value, element_tag) + return [element] + elif isinstance(python_value, list): + return itertools.chain.from_iterable( + elements_for_value(item, element_tag) for item in python_value + ) + else: + element = cElementTree.Element(element_tag) + if python_value is not None: + element.text = str(python_value) + return [element] + + # Drop timecode, rate, and link elements from roundtripping because they + # may become stale with timeline updates. + default_ignore_keys = {"timecode", "rate", "link"} + specific_ignore_keys = {"samplecharacteristics": {"timecode"}} + ignore_keys = specific_ignore_keys.get(tag, default_ignore_keys) + + # push the elements into the tree + for key, value in data_dict.items(): + if key in ignore_keys: + continue + + # We already handled the attributes + if key.startswith("@"): + continue + + elements = elements_for_value(value, key) + top_element.extend(elements) + + return top_element + + +def _element_with_item_metadata(tag, item): + """ + Given a tag name, gets the FCP XML metadata dict and creates a tree of XML + with that metadata under a top element with the provided tag. + + :param tag: The XML tag for the root element. + :param item: An otio object with a metadata dict. + """ + item_meta = item.metadata.get(META_NAMESPACE) + if item_meta: + return _dict_to_xml_tree(item_meta, tag) + + return cElementTree.Element(tag) + + +def _get_or_create_subelement(parent_element, tag): + """ + Given an element and tag name, either gets the direct child of parent with + that tag name or creates a new subelement with that tag and returns it. + + :param parent_element: The element to get or create the subelement from. + :param tag: The tag for the subelement. + """ + sub_element = parent_element.find(tag) + if sub_element is None: + sub_element = cElementTree.SubElement(parent_element, tag) + + return sub_element + + +def _make_pretty_string(tree_e): + # most of the parsing in this adapter is done with cElementTree because it + # is simpler and faster. However, the string representation it returns is + # far from elegant. Therefor we feed it through minidom to provide an xml + # with indentations. + string = cElementTree.tostring(tree_e, encoding="UTF-8", method="xml") + dom = minidom.parseString(string) + return dom.toprettyxml(indent=' ') + + +def marker_for_element(marker_element, rate): + """ + Creates an :class:`schema.Marker` for the provided element. + + :param marker_element: The XML element for the marker. + :param rate: The rate for the object the marker is attached to. + + :return: The :class:`schema.Marker` instance. + """ + # TODO: The spec doc indicates that in and out are required, but doesn't + # say they have to be locally specified, so is it possible they + # could be inherited? + marker_in = opentime.RationalTime( + float(marker_element.find("./in").text), rate + ) + marker_out_value = float(marker_element.find("./out").text) + if marker_out_value > 0: + marker_out = opentime.RationalTime( + marker_out_value, rate + ) + marker_duration = (marker_out - marker_in) + else: + marker_duration = opentime.RationalTime(rate=rate) + + marker_range = opentime.TimeRange(marker_in, marker_duration) + + md_dict = _xml_tree_to_dict(marker_element, {"in", "out", "name"}) + metadata = {META_NAMESPACE: md_dict} if md_dict else None + + return schema.Marker( + name=_name_from_element(marker_element), + marked_range=marker_range, + metadata=metadata + ) + + +def markers_from_element(element, context=None): + """ + Given an element, returns the list of markers attached to it. + + :param element: An element with one or more ``marker`` child elements. + :param context: The context for this element. + + :return: A :class:`list` of :class:`schema.Marker` instances attached + to the provided element. + """ + if context is not None: + local_context = context.context_pushing_element(element) + else: + local_context = _Context(element) + rate = _rate_from_context(local_context) + + return [marker_for_element(e, rate) for e in element.iterfind("./marker")] + + +class FCP7XMLParser: + """ + Implements parsing of an FCP XML file into an OTIO timeline. + + Parsing FCP XML elements include two concepts that require carrying state: + 1. Inheritance + 2. The id Attribute + + .. seealso:: https://developer.apple.com/library/archive/documentation/\ + AppleApplications/Reference/FinalCutPro_XML/Basics/Basics.html\ + #//apple_ref/doc/uid/TP30001154-TPXREF102 + + Inheritance is implemented using a _Context object that is pushed down + through layers of parsing. A given parsing method is passed the element to + parse into an otio object along with the context that element exists under + (e.x. a track element parsing method is given the track element and the + sequence context for that track). + + The id attribute dereferencing is handled through a lookup table stored on + parser instances and using the ``_derefed_`` methods to take an element and + find dereference elements. + """ + + _etree = None + """ The root etree for the FCP XML. """ + + _id_map = None + """ A mapping of id to the first element encountered with that id. """ + + def __init__(self, element_tree): + """ + Constructor, must be init with an xml etree. + """ + self._etree = element_tree + + self._id_map = {} + + def _derefed_element(self, element): + """ + Given an element, dereferences it by it's id attribute if needed. If + the element has an id attribute and it's our first time encountering + it, store the id. + """ + if element is None: + return element + + try: + elem_id = element.attrib["id"] + except KeyError: + return element + + return self._id_map.setdefault(elem_id, element) + + def _derefed_iterfind(self, element, path): + """ + Given an elemnt, finds elements with the provided path below and + returns an iterator of the dereferenced versions of those. + + :param element: The XML etree element. + :param path: The path to find subelements. + + :return: iterator of subelements dereferenced by id. + """ + return ( + self._derefed_element(e) for e in element.iterfind(path) + ) + + def top_level_sequences(self): + """" + Returns a list of timelines for the top-level sequences in the file. + """ + context = _Context() + + # If the tree has just sequences at the top level, this will catch them + top_iter = self._derefed_iterfind(self._etree, "./sequence") + + # If there is a project or bin at the top level, this should cath them + project_and_bin_iter = self._derefed_iterfind( + self._etree, ".//children/sequence" + ) + + # Make an iterator that will exhaust both the above + sequence_iter = itertools.chain(top_iter, project_and_bin_iter) + + return [self.timeline_for_sequence(s, context) for s in sequence_iter] + + def timeline_for_sequence(self, sequence_element, context): + """ + Returns either an :class`schema.Timeline` parsed from a sequence + element. + + :param sequence_element: The sequence element. + :param context: The context dictionary. + + :return: The appropriate OTIO object for the element. + """ + local_context = context.context_pushing_element(sequence_element) + + name = _name_from_element(sequence_element) + parsed_tags = {"name", "media", "marker", "duration"} + md_dict = _xml_tree_to_dict(sequence_element, parsed_tags) + + sequence_timecode = self._derefed_element( + sequence_element.find("./timecode") + ) + if sequence_timecode is not None: + seq_start_time = _time_from_timecode_element( + sequence_timecode, local_context + ) + else: + seq_start_time = None + + media_element = self._derefed_element(sequence_element.find("./media")) + if media_element is None: + tracks = None + else: + # Reach down into the media block and escalate metadata to the + # sequence + for media_type in media_element: + media_info_dict = _xml_tree_to_dict(media_type, {"track"}) + if media_info_dict: + media_dict = md_dict.setdefault( + "media", collections.OrderedDict() + ) + media_dict[media_type.tag] = media_info_dict + + tracks = self.stack_for_element(media_element, local_context) + tracks.name = name + + # TODO: Should we be parsing the duration tag and pad out a track with + # gap to match? + + timeline = schema.Timeline( + name=name, + global_start_time=seq_start_time, + metadata={META_NAMESPACE: md_dict} if md_dict else {}, + ) + timeline.tracks = tracks + + # Push the sequence markers onto the top stack + markers = markers_from_element(sequence_element, context) + timeline.tracks.markers.extend(markers) + + return timeline + + def stack_for_element(self, element, context): + """ + Given an element, parses out track information as a stack. + + :param element: The element under which to find the tracks (typically + a ``media`` element. + :param context: The current parser context. + + :return: A :class:`schema.Stack` of the tracks. + """ + # Determine the context + local_context = context.context_pushing_element(element) + + tracks = [] + media_type_elements = self._derefed_iterfind(element, "./") + for media_type_element in media_type_elements: + try: + track_kind = _track_kind_from_element(media_type_element) + except ValueError: + # Unexpected element + continue + + is_audio = (track_kind == schema.TrackKind.Audio) + track_elements = self._derefed_iterfind( + media_type_element, "./track" + ) + for track_element in track_elements: + if is_audio and not _is_primary_audio_channel(track_element): + continue + + tracks.append( + self.track_for_element( + track_element, track_kind, local_context + ) + ) + + markers = markers_from_element(element, context) + + stack = schema.Stack( + children=tracks, + markers=markers, + name=_name_from_element(element), + ) + + return stack + + def track_for_element(self, track_element, track_kind, context): + """ + Given a track element, constructs the OTIO track. + + :param track_element: The track XML element. + :param track_kind: The :class:`schema.TrackKind` for the track. + :param context: The context dict for this track. + """ + local_context = context.context_pushing_element(track_element) + name_element = track_element.find("./name") + track_name = (name_element.text if name_element is not None else None) + + timeline_item_tags = {"clipitem", "generatoritem", "transitionitem"} + + md_dict = _xml_tree_to_dict(track_element, timeline_item_tags) + track_metadata = {META_NAMESPACE: md_dict} if md_dict else None + + track = schema.Track( + name=track_name, + kind=track_kind, + metadata=track_metadata, + ) + + # Iterate through and parse track items + track_rate = _rate_from_context(local_context) + current_timeline_time = opentime.RationalTime(0, track_rate) + head_transition_element = None + for i, item_element in enumerate(track_element): + if item_element.tag not in timeline_item_tags: + continue + + item_element = self._derefed_element(item_element) + + # Do a lookahead to try and find the tail transition item + try: + tail_transition_element = track_element[i + 1] + if tail_transition_element.tag != "transitionitem": + tail_transition_element = None + else: + tail_transition_element = self._derefed_element( + tail_transition_element + ) + except IndexError: + tail_transition_element = None + + track_item, item_range = self.item_and_timing_for_element( + item_element, + head_transition_element, + tail_transition_element, + local_context, + ) + + # Insert gap between timeline cursor and the new item if needed. + if current_timeline_time < item_range.start_time: + gap_duration = (item_range.start_time - current_timeline_time) + gap_range = opentime.TimeRange( + duration=gap_duration.rescaled_to(track_rate) + ) + track.append(schema.Gap(source_range=gap_range)) + + # Add the item and advance the timeline cursor + track.append(track_item) + current_timeline_time = item_range.end_time_exclusive() + + # Stash the element for the next iteration if it's a transition + if item_element.tag == "transitionitem": + head_transition_element = item_element + + return track + + def media_reference_for_file_element(self, file_element, context): + """ + Given a file XML element, returns the + :class`schema.ExternalReference`. + + :param file_element: The file xml element. + :param context: The parent context dictionary. + + :return: An :class:`schema.ExternalReference`. + """ + local_context = context.context_pushing_element(file_element) + media_ref_rate = _rate_from_context(local_context) + + name = _name_from_element(file_element) + + # Get the full metadata + metadata_ignore_keys = {"duration", "name", "pathurl"} + md_dict = _xml_tree_to_dict(file_element, metadata_ignore_keys) + metadata_dict = {META_NAMESPACE: md_dict} if md_dict else None + + # Determine the file path + path_element = file_element.find("./pathurl") + if path_element is not None: + path = path_element.text + else: + path = None + + # Find the timing + timecode_element = file_element.find("./timecode") + if timecode_element is not None: + start_time = _time_from_timecode_element(timecode_element) + start_time = start_time.rescaled_to(media_ref_rate) + else: + start_time = opentime.RationalTime(0, media_ref_rate) + + duration_element = file_element.find("./duration") + if duration_element is not None: + duration = opentime.RationalTime( + float(duration_element.text), media_ref_rate + ) + available_range = opentime.TimeRange(start_time, duration) + elif timecode_element is not None: + available_range = opentime.TimeRange( + start_time, + opentime.RationalTime(0, media_ref_rate), + ) + else: + available_range = None + + if path is None: + media_reference = schema.MissingReference( + name=name, + available_range=available_range, + metadata=metadata_dict, + ) + else: + media_reference = schema.ExternalReference( + target_url=path, + available_range=available_range, + metadata=metadata_dict, + ) + media_reference.name = name + + return media_reference + + def media_reference_for_effect_element(self, effect_element): + """ + Given an effect element, returns a generator reference. + + :param effect_element: The effect for the generator. + + :return: An :class:`schema.GeneratorReference` instance. + """ + name = _name_from_element(effect_element) + md_dict = _xml_tree_to_dict(effect_element, {"name"}) + + return schema.GeneratorReference( + name=name, + metadata=({META_NAMESPACE: md_dict} if md_dict else None) + ) + + def item_and_timing_for_element( + self, item_element, head_transition, tail_transition, context + ): + """ + Given a track item, returns a tuple with the appropriate OpenTimelineIO + schema item as the first element and an + :class:`opentime.TimeRange`of theresolved timeline range the clip + occupies. + + :param item_element: The track item XML node. + :param head_transition: The xml element for the transition immediately + before or ``None``. + :param tail_transition: The xml element for the transition immediately + after or ``None``. + :param context: The context dictionary. + + :return: An :class:`core.Item` subclass instance and + :class:`opentime.TimeRange` for the item. + """ + parent_rate = _rate_from_context(context) + + # Establish the start/end time in the timeline + start_value = int(item_element.find("./start").text) + end_value = int(item_element.find("./end").text) + + if start_value == -1: + # determine based on the cut point of the head transition + start = _transition_cut_point(head_transition, context) + + # This offset is needed to determing how much to advance from the + # clip media's in time. Duration accounts for this offset for the + # out time. + transition_rate = _rate_from_context( + context.context_pushing_element(head_transition) + ) + start_offset = start - opentime.RationalTime( + int(head_transition.find('./start').text), transition_rate + ) + else: + start = opentime.RationalTime(start_value, parent_rate) + start_offset = opentime.RationalTime() + + if end_value == -1: + # determine based on the cut point of the tail transition + end = _transition_cut_point(tail_transition, context) + else: + end = opentime.RationalTime(end_value, parent_rate) + + item_range = opentime.TimeRange(start, (end - start)) + + # Get the metadata dictionary for the item + item_metadata_ignore_keys = { + "name", + "start", + "end", + "in", + "out", + "duration", + "file", + "marker", + "effect", + "rate", + "sequence", + } + metadata_dict = _xml_tree_to_dict( + item_element, item_metadata_ignore_keys + ) + + # deserialize the item + if item_element.tag in {"clipitem", "generatoritem"}: + item = self.clip_for_element( + item_element, item_range, start_offset, context + ) + elif item_element.tag == "transitionitem": + item = self.transition_for_element(item_element, context) + else: + name = "unknown-{}".format(item_element.tag) + item = core.Item(name=name, source_range=item_range) + + if metadata_dict: + item.metadata.setdefault(META_NAMESPACE, {}).update(metadata_dict) + + return (item, item_range) + + def clip_for_element( + self, clipitem_element, item_range, start_offset, context + ): + """ + Given a clipitem xml element, returns an :class:`schema.Clip`. + + :param clipitem_element: The element to create a clip for. + :param item_range: The time range in the timeline the clip occupies. + :param start_offset: The amount by which the ``in`` time of the clip + source should be advanced (usually due to a transition). + :param context: The parent context for the clip. + + :return: The :class:`schema.Clip` instance. + """ + local_context = context.context_pushing_element(clipitem_element) + + name = _name_from_element(clipitem_element) + + file_element = self._derefed_element(clipitem_element.find("./file")) + sequence_element = self._derefed_element( + clipitem_element.find("./sequence") + ) + if clipitem_element.tag == "generatoritem": + generator_effect_element = clipitem_element.find( + "./effect[effecttype='generator']" + ) + else: + generator_effect_element = None + + media_start_time = opentime.RationalTime() + if sequence_element is not None: + item = self.stack_for_element(sequence_element, local_context) + # TODO: is there an applicable media start time we should be + # using from nested sequences? + elif file_element is not None or generator_effect_element is not None: + if file_element is not None: + media_reference = self.media_reference_for_file_element( + file_element, local_context + ) + # See if there is a start offset + timecode_element = file_element.find("./timecode") + if timecode_element is not None: + media_start_time = _time_from_timecode_element( + timecode_element + ) + elif generator_effect_element is not None: + media_reference = self.media_reference_for_effect_element( + generator_effect_element + ) + + item = schema.Clip( + name=name, + media_reference=media_reference, + ) + else: + raise TypeError( + 'Type of clip item is not supported {}'.format( + _element_identification_string(clipitem_element) + ) + ) + + # Add the markers + markers = markers_from_element(clipitem_element, context) + item.markers.extend(markers) + + # Find the in time (source time relative to media start) + clip_rate = _rate_from_context(local_context) + in_value = float(clipitem_element.find('./in').text) + in_time = opentime.RationalTime(in_value, clip_rate) + + # Offset the "in" time by the start offset of the media + soure_start_time = in_time + media_start_time + start_offset + duration = item_range.duration + + # Source Range is the item range expressed in the clip's rate (for now) + source_range = opentime.TimeRange( + soure_start_time.rescaled_to(clip_rate), + duration.rescaled_to(clip_rate), + ) + + item.source_range = source_range + + # Parse the filters + filter_iter = self._derefed_iterfind(clipitem_element, "./filter") + for filter_element in filter_iter: + item.effects.append( + self.effect_from_filter_element(filter_element) + ) + + return item + + def effect_from_filter_element(self, filter_element): + """ + Given a filter element, creates an :class:`schema.Effect`. + + :param filter_element: The ``filter`` element containing the effect. + + :return: The effect instance. + """ + effect_element = filter_element.find("./effect") + + if effect_element is None: + raise ValueError( + "could not find effect in filter: {}".format(filter_element) + ) + + name = effect_element.find("./name").text + + effect_metadata = _xml_tree_to_dict(effect_element, {"name"}) + + return schema.Effect( + name, + metadata={META_NAMESPACE: effect_metadata}, + ) + + def transition_for_element(self, item_element, context): + """ + Creates an OTIO transition for the provided transition element. + + :param item_element: The element to create a transition for. + :param context: The parent context for the element. + + :return: The :class:`schema.Transition` instance. + """ + # start and end times are in the parent's rate + rate = _rate_from_context(context) + start = opentime.RationalTime( + int(item_element.find('./start').text), + rate + ) + end = opentime.RationalTime( + int(item_element.find('./end').text), + rate + ) + cut_point = _transition_cut_point(item_element, context) + + transition = schema.Transition( + name=item_element.find('./effect/name').text, + transition_type=schema.TransitionTypes.SMPTE_Dissolve, + in_offset=cut_point - start, + out_offset=end - cut_point, + ) + + return transition + + +# ------------------------ +# building single track +# ------------------------ + + +def _backreference_for_item(item, tag, br_map): + """ + Given an item, determines what the id in the backreference map should be. + If the item is already tracked in the map, it will be returned, otherwise + a new id will be minted. + + .. note:: ``br_map`` may be mutated by this function. ``br_map`` is + intended to be an opaque data structure and only accessed through this + function, the structure of data in br_map may change. + + :param item: The :class:`core.SerializableObject` to create an id for. + :param tag: The tag name that will be used for object in xml. + :param br_map: The dictionary containing backreference information + generated so far. + + :return: A 2-tuple of (id_string, is_new_id) where the ``id_string`` is + the value for the xml id attribute and ``is_new_id`` is ``True`` when + this is the first time that id was encountered. + """ + # br_map is structured as a dictionary with tags as keys, and dictionaries + # of hash to id int as values. + + def id_string(id_int): + return "{}-{}".format(tag, id_int) + + # Determine how to uniquely identify the referenced item + if isinstance(item, schema.ExternalReference): + item_hash = hash(str(item.target_url)) + else: + # TODO: This may become a performance issue. It means that every + # non-ref object is serialized to json and hashed each time it's + # encountered. + item_hash = hash( + core.json_serializer.serialize_json_to_string(item) + ) + + is_new_id = False + item_id = br_map.get(tag, {}).get(item_hash) + if item_id is not None: + return (id_string(item_id), is_new_id) + + # This is a new id, figure out what it should be. + is_new_id = True + + # Attempt to preserve the ID from the input metadata. + preferred_id = None + orig_id_string = item.metadata.get(META_NAMESPACE, {}).get("@id") + if orig_id_string is not None: + orig_id_match = ID_RE.match(orig_id_string) + if orig_id_match is not None: + match_groups = orig_id_match.groupdict() + orig_tagname = match_groups["tag"] + if orig_tagname == tag: + preferred_id = int(match_groups["id"]) + + # Generate an id by finding the lowest value in a contiguous range not + # colliding with an existing value + tag_id_map = br_map.setdefault(tag, {}) + existing_ids = set(tag_id_map.values()) + if preferred_id is not None and preferred_id not in existing_ids: + item_id = preferred_id + else: + # Make a range from 1 including the ID after the largest assigned + # (hence the +2 since range is non-inclusive on the upper bound) + max_assigned_id = max(existing_ids) if existing_ids else 0 + max_possible_id = (max_assigned_id + 2) + possible_ids = set(range(1, max_possible_id)) + + # Select the lowest unassigned ID + item_id = min(possible_ids.difference(existing_ids)) + + # Store the created id + tag_id_map[item_hash] = item_id + + return (id_string(item_id), is_new_id) + + +def _backreference_build(tag): + """ + A decorator for functions creating XML elements to implement the id system + described in FCP XML. + + This wrapper determines if the otio item is equivalent to one encountered + before with the provided tag name. If the item hasn't been encountered then + the wrapped function will be invoked and the XML element from that function + will have the ``id`` attribute set and be stored in br_map. + If the item is equivalent to a previously provided item, the wrapped + function won't be invoked and a simple tag with the previous instance's id + will be returned instead. + + The wrapped function must: + - Have the otio item as the first positional argument. + - Have br_map (backreference map, a dictionary) as the last positional + arg. br_map stores the state for encountered items. + + :param tag: The xml tag of the element the wrapped function generates. + """ + # We can also encode these back-references if an item is accessed multiple + # times. To do this we store an id attribute on the element. For back- + # references we then only need to return an empty element of that type with + # the id we logged before + + def singleton_decorator(func): + @functools.wraps(func) + def wrapper(item, *args, **kwargs): + br_map = args[-1] + + item_id, id_is_new = _backreference_for_item(item, tag, br_map) + + # if the item exists in the map already, we should use the + # abbreviated XML element referring to the original + if not id_is_new: + return cElementTree.Element(tag, id=item_id) + + # This is the first time for this unique item, it needs it's full + # XML. Get the element generated by the wrapped function and add + # the id attribute. + elem = func(item, *args, **kwargs) + elem.attrib["id"] = item_id + + return elem + + return wrapper + + return singleton_decorator + + +def _append_new_sub_element(parent, tag, attrib=None, text=None): + """ + Creates a sub-element with the provided tag, attributes, and text. + + This is a convenience because the :class:`SubElement` constructor does not + provide the ability to set ``text``. + + :param parent: The parent element. + :param tag: The tag string for the element. + :param attrib: An optional dictionary of attributes for the element. + :param text: Optional text value for the element. + + :return: The new XML element. + """ + elem = cElementTree.SubElement(parent, tag, **attrib or {}) + if text is not None: + elem.text = text + + return elem + + +def _build_rate(fps): + """ + Given a framerate, makes a ``rate`` xml tree. + + :param fps: The framerate. + :return: The fcp xml ``rate`` tree. + """ + rate = math.ceil(fps) + + rate_e = cElementTree.Element('rate') + _append_new_sub_element(rate_e, 'timebase', text=str(int(rate))) + _append_new_sub_element( + rate_e, + 'ntsc', + text='FALSE' if rate == fps else 'TRUE' + ) + return rate_e + + +def _build_timecode(time, fps, drop_frame=False, additional_metadata=None): + """ + Makes a timecode xml element tree. + + .. warning:: The drop_frame parameter is currently ignored and + auto-determined by rate. This is because the underlying otio timecode + conversion assumes DFTC based on rate. + + :param time: The :class:`opentime.RationalTime` for the timecode. + :param fps: The framerate for the timecode. + :param drop_frame: If True, generates drop-frame timecode. + :param additional_metadata: A dictionary with other metadata items like + ``field``, ``reel``, ``source``, and ``format``. It is assumed this + dictionary is of the form generated by :func:`_xml_tree_to_dict` when + the file was read originally. + + :return: The ``timecode`` element. + """ + if additional_metadata: + # Only allow legal child items for the timecode element + filtered = { + k: v for k, v in additional_metadata.items() + if k in {"field", "reel", "source", "format"} + } + tc_element = _dict_to_xml_tree(filtered, "timecode") + else: + tc_element = cElementTree.Element("timecode") + + tc_element.append(_build_rate(fps)) + rate_is_not_ntsc = (tc_element.find('./rate/ntsc').text == "FALSE") + if drop_frame and rate_is_not_ntsc: + tc_fps = fps * (1000 / 1001.0) + else: + tc_fps = fps + + # Get the time values + tc_time = opentime.RationalTime(time.value_rescaled_to(fps), tc_fps) + tc_string = opentime.to_timecode(tc_time, tc_fps, drop_frame) + + _append_new_sub_element(tc_element, "string", text=tc_string) + + frame_number = int(round(time.value)) + _append_new_sub_element( + tc_element, "frame", text="{:.0f}".format(frame_number) + ) + + drop_frame = (";" in tc_string) + display_format = "DF" if drop_frame else "NDF" + _append_new_sub_element(tc_element, "displayformat", text=display_format) + + return tc_element + + +def _build_item_timings( + item_e, + item, + timeline_range, + transition_offsets, + timecode +): + # source_start is absolute time taking into account the timecode of the + # media. But xml regards the source in point from the start of the media. + # So we subtract the media timecode. + item_rate = item.source_range.start_time.rate + source_start = (item.source_range.start_time - timecode) + source_start = source_start.rescaled_to(item_rate) + + source_end = (item.source_range.end_time_exclusive() - timecode) + source_end = source_end.rescaled_to(item_rate) + + start = '{:.0f}'.format(timeline_range.start_time.value) + end = '{:.0f}'.format(timeline_range.end_time_exclusive().value) + + item_e.append(_build_rate(item_rate)) + + if transition_offsets[0] is not None: + start = '-1' + source_start -= transition_offsets[0] + if transition_offsets[1] is not None: + end = '-1' + source_end += transition_offsets[1] + + _append_new_sub_element( + item_e, 'duration', + text='{:.0f}'.format(item.source_range.duration.value) + ) + _append_new_sub_element(item_e, 'start', text=start) + _append_new_sub_element(item_e, 'end', text=end) + _append_new_sub_element( + item_e, + 'in', + text='{:.0f}'.format(source_start.value) + ) + _append_new_sub_element( + item_e, + 'out', + text='{:.0f}'.format(source_end.value) + ) + + +@_backreference_build('file') +def _build_empty_file(media_ref, parent_range, br_map): + file_e = _element_with_item_metadata("file", media_ref) + _append_new_sub_element(file_e, "name", text=media_ref.name) + + if media_ref.available_range is not None: + available_range = media_ref.available_range + else: + available_range = opentime.TimeRange( + opentime.RationalTime(0, parent_range.start_time.rate), + parent_range.duration, + ) + + ref_rate = available_range.start_time.rate + file_e.append(_build_rate(ref_rate)) + + # Only provide a duration if one came from the media, don't invent one. + # For example, Slugs have no duration specified. + if media_ref.available_range: + duration = available_range.duration.rescaled_to(ref_rate) + _append_new_sub_element( + file_e, + 'duration', + text='{:.0f}'.format(duration.value), + ) + + # timecode + ref_tc_metadata = media_ref.metadata.get(META_NAMESPACE, {}).get( + "timecode" + ) + tc_element = _build_timecode_from_metadata( + available_range.start_time, ref_tc_metadata + ) + file_e.append(tc_element) + + file_media_e = _get_or_create_subelement(file_e, "media") + if file_media_e.find("video") is None: + _append_new_sub_element(file_media_e, "video") + + return file_e + + +@_backreference_build('file') +def _build_file(media_reference, br_map): + file_e = _element_with_item_metadata("file", media_reference) + + available_range = media_reference.available_range + url_path = _url_to_path(media_reference.target_url) + + file_name = ( + media_reference.name if media_reference.name + else os.path.basename(url_path) + ) + _append_new_sub_element(file_e, 'name', text=file_name) + _append_new_sub_element(file_e, 'pathurl', text=media_reference.target_url) + + # timing info + file_e.append(_build_rate(available_range.start_time.rate)) + _append_new_sub_element( + file_e, 'duration', + text='{:.0f}'.format(available_range.duration.value) + ) + + # timecode + ref_tc_metadata = media_reference.metadata.get(META_NAMESPACE, {}).get( + "timecode" + ) + tc_element = _build_timecode_from_metadata( + available_range.start_time, ref_tc_metadata + ) + file_e.append(tc_element) + + # we need to flag the file reference with the content types, otherwise it + # will not get recognized + # TODO: We should use a better method for this. Perhaps pre-walk the + # timeline and find all the track kinds this media is present in? + if not file_e.find("media"): + file_media_e = _get_or_create_subelement(file_e, "media") + + audio_exts = {'.wav', '.aac', '.mp3', '.aif', '.aiff', '.m4a'} + has_video = (os.path.splitext(url_path)[1].lower() not in audio_exts) + if has_video and file_media_e.find("video") is None: + _append_new_sub_element(file_media_e, "video") + + # TODO: This is assuming all files have an audio track. Not sure what + # the implications of that are. + if file_media_e.find("audio") is None: + _append_new_sub_element(file_media_e, "audio") + + return file_e + + +def _build_transition_item( + transition_item, + timeline_range, + transition_offsets, + br_map, +): + transition_e = _element_with_item_metadata( + "transitionitem", transition_item + ) + _append_new_sub_element( + transition_e, + 'start', + text='{:.0f}'.format(timeline_range.start_time.value) + ) + _append_new_sub_element( + transition_e, + 'end', + text='{:.0f}'.format(timeline_range.end_time_exclusive().value) + ) + + # Only add an alignment if it didn't already come in from the metadata dict + if transition_e.find("alignment") is None: + # default center aligned + alignment = "center" + if not transition_item.in_offset.value: + alignment = 'start-black' + elif not transition_item.out_offset.value: + alignment = 'end-black' + + _append_new_sub_element(transition_e, 'alignment', text=alignment) + # todo support 'start' and 'end' alignment + + transition_e.append(_build_rate(timeline_range.start_time.rate)) + + # Only add an effect if it didn't already come in from the metadata dict + if not transition_e.find("./effect"): + try: + effectid = transition_item.metadata[META_NAMESPACE]["effectid"] + except KeyError: + effectid = "Cross Dissolve" + + effect_e = _append_new_sub_element(transition_e, 'effect') + _append_new_sub_element(effect_e, 'name', text=transition_item.name) + _append_new_sub_element(effect_e, 'effectid', text=effectid) + _append_new_sub_element(effect_e, 'effecttype', text='transition') + _append_new_sub_element(effect_e, 'mediatype', text='video') + + return transition_e + + +@_backreference_build("clipitem") +def _build_clip_item_without_media( + clip_item, + timeline_range, + transition_offsets, + br_map, +): + # TODO: Does this need to be a separate function or could it be unified + # with _build_clip_item? + clip_item_e = _element_with_item_metadata("clipitem", clip_item) + if "frameBlend" not in clip_item_e.attrib: + clip_item_e.attrib["frameBlend"] = "FALSE" + + if clip_item.media_reference.available_range: + media_start_time = clip_item.media_reference.available_range.start_time + else: + media_start_time = opentime.RationalTime( + 0, timeline_range.start_time.rate + ) + + _append_new_sub_element(clip_item_e, 'name', text=clip_item.name) + clip_item_e.append( + _build_empty_file( + clip_item.media_reference, timeline_range, br_map + ) + ) + clip_item_e.extend([_build_marker(m) for m in clip_item.markers]) + + _build_item_timings( + clip_item_e, + clip_item, + timeline_range, + transition_offsets, + media_start_time, + ) + + return clip_item_e + + +@_backreference_build("clipitem") +def _build_clip_item(clip_item, timeline_range, transition_offsets, br_map): + is_generator = isinstance( + clip_item.media_reference, schema.GeneratorReference + ) + + tagname = "generatoritem" if is_generator else "clipitem" + clip_item_e = _element_with_item_metadata(tagname, clip_item) + if "frameBlend" not in clip_item_e.attrib: + clip_item_e.attrib["frameBlend"] = "FALSE" + + if is_generator: + clip_item_e.append(_build_generator_effect(clip_item, br_map)) + else: + clip_item_e.append(_build_file(clip_item.media_reference, br_map)) + + # set the clip name from the media reference if not defined on the clip + if clip_item.name is not None: + name = clip_item.name + elif is_generator: + name = clip_item.media_reference.name + else: + url_path = _url_to_path(clip_item.media_reference.target_url) + name = os.path.basename(url_path) + + _append_new_sub_element(clip_item_e, 'name', text=name) + + if clip_item.media_reference.available_range: + clip_item_e.append( + _build_rate(clip_item.source_range.start_time.rate) + ) + clip_item_e.extend(_build_marker(m) for m in clip_item.markers) + + if clip_item.media_reference.available_range: + timecode = clip_item.media_reference.available_range.start_time + else: + timecode = opentime.RationalTime( + 0, clip_item.source_range.start_time.rate + ) + + _build_item_timings( + clip_item_e, + clip_item, + timeline_range, + transition_offsets, + timecode + ) + + return clip_item_e + + +def _build_generator_effect(clip_item, br_map): + """ + Builds an effect element for the generator ref on the provided clip item. + + :param clip_item: a clip with a :class:`schema.GeneratorReference` as + its ``media_reference``. + :param br_map: The backreference map. + """ + # Since we don't support effects in a standard way, just try and build + # based on the metadata provided at deserialization so we can roundtrip + generator_ref = clip_item.media_reference + try: + fcp_xml_effect_info = generator_ref.metadata[META_NAMESPACE] + except KeyError: + return _build_empty_file( + generator_ref, + clip_item.source_range, + br_map, + ) + + # Get the XML Tree built from the metadata + effect_element = _dict_to_xml_tree(fcp_xml_effect_info, "effect") + + # Validate the metadata and make sure it contains the required elements + for required in ("effectid", "effecttype", "mediatype", "effectcategory"): + if effect_element.find(required) is None: + return _build_empty_file( + generator_ref, + clip_item.source_range, + br_map, + ) + + # Add the name + _append_new_sub_element(effect_element, "name", text=generator_ref.name) + + return effect_element + + +@_backreference_build("clipitem") +def _build_track_item(track, timeline_range, transition_offsets, br_map): + clip_item_e = _element_with_item_metadata("clipitem", track) + if "frameBlend" not in clip_item_e.attrib: + clip_item_e.attrib["frameBlend"] = "FALSE" + + _append_new_sub_element( + clip_item_e, + 'name', + text=os.path.basename(track.name) + ) + + track_e = _build_sequence_for_stack(track, timeline_range, br_map) + + clip_item_e.append(_build_rate(track.source_range.start_time.rate)) + clip_item_e.extend([_build_marker(m) for m in track.markers]) + clip_item_e.append(track_e) + timecode = opentime.RationalTime(0, timeline_range.start_time.rate) + + _build_item_timings( + clip_item_e, + track, + timeline_range, + transition_offsets, + timecode + ) + + return clip_item_e + + +def _build_item(item, timeline_range, transition_offsets, br_map): + if isinstance(item, schema.Transition): + return _build_transition_item( + item, + timeline_range, + transition_offsets, + br_map + ) + elif isinstance(item, schema.Clip): + if isinstance( + item.media_reference, + schema.MissingReference + ): + return _build_clip_item_without_media( + item, + timeline_range, + transition_offsets, + br_map + ) + else: + return _build_clip_item( + item, + timeline_range, + transition_offsets, + br_map + ) + elif isinstance(item, schema.Stack): + return _build_track_item( + item, + timeline_range, + transition_offsets, + br_map + ) + else: + raise ValueError('Unsupported item: ' + str(item)) + + +def _build_top_level_track(track, track_rate, br_map): + track_e = _element_with_item_metadata("track", track) + + for n, item in enumerate(track): + if isinstance(item, schema.Gap): + continue + + transition_offsets = [None, None] + previous_item = track[n - 1] if n > 0 else None + next_item = track[n + 1] if n + 1 < len(track) else None + if not isinstance(item, schema.Transition): + # find out if this item has any neighboring transition + if isinstance(previous_item, schema.Transition): + if previous_item.out_offset.value: + transition_offsets[0] = previous_item.in_offset + else: + transition_offsets[0] = None + if isinstance(next_item, schema.Transition): + if next_item.in_offset.value: + transition_offsets[1] = next_item.out_offset + else: + transition_offsets[1] = None + + timeline_range = track.range_of_child_at_index(n) + timeline_range = opentime.TimeRange( + timeline_range.start_time.rescaled_to(track_rate), + timeline_range.duration.rescaled_to(track_rate) + ) + track_e.append( + _build_item(item, timeline_range, transition_offsets, br_map) + ) + + return track_e + + +def _build_marker(marker): + marker_e = _element_with_item_metadata("marker", marker) + + marked_range = marker.marked_range + + _append_new_sub_element(marker_e, 'name', text=marker.name) + _append_new_sub_element( + marker_e, 'in', + text='{:.0f}'.format(marked_range.start_time.value) + ) + _append_new_sub_element(marker_e, 'out', text='-1') + + return marker_e + + +def _build_timecode_from_metadata(time, tc_metadata=None): + """ + Makes a timecode element with the given time and (if available) + ```timecode`` metadata stashed on input. + + :param time: The :class:`opentime.RationalTime` to encode. + :param tc_metadata: The xml dict for the ``timecode`` element populated + on read. + + :return: A timecode element. + """ + if tc_metadata is None: + tc_metadata = {} + + try: + # Parse the rate in the preserved metadata, if available + tc_rate = _rate_for_element( + _dict_to_xml_tree(tc_metadata["rate"], "rate") + ) + except KeyError: + # Default to the rate in the start time + tc_rate = time.rate + + drop_frame = (tc_metadata.get("displayformat", "NDF") == "DF") + + return _build_timecode( + time, + tc_rate, + drop_frame, + additional_metadata=tc_metadata, + ) + + +@_backreference_build('sequence') +def _build_sequence_for_timeline(timeline, timeline_range, br_map): + sequence_e = _element_with_item_metadata("sequence", timeline) + + _add_stack_elements_to_sequence( + timeline.tracks, sequence_e, timeline_range, br_map + ) + + # In the case of timelines, use the timeline name rather than the stack + # name. + if timeline.name: + sequence_e.find('./name').text = timeline.name + + # Add the sequence global start + if timeline.global_start_time is not None: + seq_tc_metadata = timeline.metadata.get(META_NAMESPACE, {}).get( + "timecode" + ) + tc_element = _build_timecode_from_metadata( + timeline.global_start_time, seq_tc_metadata + ) + sequence_e.append(tc_element) + + return sequence_e + + +@_backreference_build('sequence') +def _build_sequence_for_stack(stack, timeline_range, br_map): + sequence_e = _element_with_item_metadata("sequence", stack) + + _add_stack_elements_to_sequence(stack, sequence_e, timeline_range, br_map) + + return sequence_e + + +def _add_stack_elements_to_sequence(stack, sequence_e, timeline_range, br_map): + _append_new_sub_element(sequence_e, 'name', text=stack.name) + _append_new_sub_element( + sequence_e, 'duration', + text='{:.0f}'.format(timeline_range.duration.value) + ) + sequence_e.append(_build_rate(timeline_range.start_time.rate)) + track_rate = timeline_range.start_time.rate + + media_e = _get_or_create_subelement(sequence_e, "media") + video_e = _get_or_create_subelement(media_e, 'video') + audio_e = _get_or_create_subelement(media_e, 'audio') + + for track in stack: + track_elements = _build_top_level_track(track, track_rate, br_map) + if track.kind == schema.TrackKind.Video: + video_e.append(track_elements) + elif track.kind == schema.TrackKind.Audio: + audio_e.append(track_elements) + + for marker in stack.markers: + sequence_e.append(_build_marker(marker)) + + +def _build_collection(collection, br_map): + tracks = [] + for item in collection: + if not isinstance(item, schema.Timeline): + continue + + timeline_range = opentime.TimeRange( + start_time=item.global_start_time, + duration=item.duration() + ) + tracks.append( + _build_sequence_for_timeline(item, timeline_range, br_map) + ) + + return tracks + + +# -------------------- +# adapter requirements +# -------------------- + +def read_from_string(input_str): + tree = cElementTree.fromstring(input_str) + + parser = FCP7XMLParser(tree) + sequences = parser.top_level_sequences() + + if len(sequences) == 1: + return sequences[0] + elif len(sequences) > 1: + return schema.SerializableCollection( + name="Sequences", + children=sequences, + ) + else: + raise ValueError('No top-level sequences found') + + +def write_to_string(input_otio): + tree_e = cElementTree.Element('xmeml', version="4") + project_e = _append_new_sub_element(tree_e, 'project') + _append_new_sub_element(project_e, 'name', text=input_otio.name) + children_e = _append_new_sub_element(project_e, 'children') + + br_map = collections.defaultdict(dict) + + if isinstance(input_otio, schema.Timeline): + timeline_range = opentime.TimeRange( + start_time=input_otio.global_start_time, + duration=input_otio.duration() + ) + children_e.append( + _build_sequence_for_timeline( + input_otio, timeline_range, br_map + ) + ) + elif isinstance(input_otio, schema.SerializableCollection): + children_e.extend( + _build_collection(input_otio, br_map) + ) + + return _make_pretty_string(tree_e) diff --git a/pype/vendor/python/python_2/opentimelineio/adapters/otio_json.py b/pype/vendor/python/python_2/opentimelineio/adapters/otio_json.py new file mode 100644 index 0000000000..66b8db2904 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/adapters/otio_json.py @@ -0,0 +1,48 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""This adapter lets you read and write native .otio files""" + +from .. import ( + core +) + + +# @TODO: Implement out of process plugins that hand around JSON + + +def read_from_file(filepath): + return core.deserialize_json_from_file(filepath) + + +def read_from_string(input_str): + return core.deserialize_json_from_string(input_str) + + +def write_to_string(input_otio): + return core.serialize_json_to_string(input_otio) + + +def write_to_file(input_otio, filepath): + return core.serialize_json_to_file(input_otio, filepath) diff --git a/pype/vendor/python/python_2/opentimelineio/algorithms/__init__.py b/pype/vendor/python/python_2/opentimelineio/algorithms/__init__.py new file mode 100644 index 0000000000..e211598bb3 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/algorithms/__init__.py @@ -0,0 +1,44 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Algorithms for OTIO objects.""" + +# flake8: noqa +from .track_algo import ( + track_trimmed_to_range, + track_with_expanded_transitions +) + +from .stack_algo import ( + flatten_stack, + top_clip_at_time, +) + +from .filter import ( + filtered_composition, + filtered_with_sequence_context +) +from .timeline_algo import ( + timeline_trimmed_to_range +) diff --git a/pype/vendor/python/python_2/opentimelineio/algorithms/filter.py b/pype/vendor/python/python_2/opentimelineio/algorithms/filter.py new file mode 100644 index 0000000000..8f9e2ed41b --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/algorithms/filter.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Algorithms for filtering OTIO files. """ + +import copy + +from .. import ( + schema +) + + +def _is_in(thing, container): + return any(thing is item for item in container) + + +def _isinstance_in(child, typelist): + return any(isinstance(child, t) for t in typelist) + + +def filtered_composition( + root, + unary_filter_fn, + types_to_prune=None, +): + """Filter a deep copy of root (and children) with unary_filter_fn. + + types_to_prune:: tuple of types, example: (otio.schema.Gap,...) + + 1. Make a deep copy of root + 2. Starting with root, perform a depth first traversal + 3. For each item (including root): + a. if types_to_prune is not None and item is an instance of a type + in types_to_prune, prune it from the copy, continue. + b. Otherwise, pass the copy to unary_filter_fn. If unary_filter_fn: + I. returns an object: add it to the copy, replacing original + II. returns a tuple: insert it into the list, replacing original + III. returns None: prune it + 4. If an item is pruned, do not traverse its children + 5. Return the new deep copy. + + EXAMPLE 1 (filter): + If your unary function is: + def fn(thing): + if thing.name == B: + return thing' # some transformation of B + else: + return thing + + If you have a track: [A,B,C] + + filtered_composition(track, fn) => [A,B',C] + + EXAMPLE 2 (prune): + If your unary function is: + def fn(thing): + if thing.name == B: + return None + else: + return thing + + filtered_composition(track, fn) => [A,C] + + EXAMPLE 3 (expand): + If your unary function is: + def fn(thing): + if thing.name == B: + return tuple(B_1,B_2,B_3) + else: + return thing + + filtered_composition(track, fn) => [A,B_1,B_2,B_3,C] + + EXAMPLE 4 (prune gaps): + track :: [Gap, A, Gap] + filtered_composition( + track, lambda _:_, types_to_prune=(otio.schema.Gap,)) => [A] + """ + + # deep copy everything + mutable_object = copy.deepcopy(root) + + prune_list = set() + + header_list = [mutable_object] + + if isinstance(mutable_object, schema.Timeline): + header_list.append(mutable_object.tracks) + + iter_list = header_list + list(mutable_object.each_child()) + + for child in iter_list: + if _safe_parent(child) is not None and _is_in(child.parent(), prune_list): + prune_list.add(child) + continue + + parent = None + child_index = None + if _safe_parent(child) is not None: + child_index = child.parent().index(child) + parent = child.parent() + del child.parent()[child_index] + + # first try to prune + if (types_to_prune and _isinstance_in(child, types_to_prune)): + result = None + # finally call the user function + else: + result = unary_filter_fn(child) + + if child is mutable_object: + mutable_object = result + + if result is None: + prune_list.add(child) + continue + + if type(result) is not tuple: + result = [result] + + if parent is not None: + parent[child_index:child_index] = result + + return mutable_object + + +def _safe_parent(child): + if hasattr(child, 'parent'): + return child.parent() + return None + + +def filtered_with_sequence_context( + root, + reduce_fn, + types_to_prune=None, +): + """Filter a deep copy of root (and children) with reduce_fn. + + reduce_fn::function(previous_item, current, next_item) (see below) + types_to_prune:: tuple of types, example: (otio.schema.Gap,...) + + 1. Make a deep copy of root + 2. Starting with root, perform a depth first traversal + 3. For each item (including root): + a. if types_to_prune is not None and item is an instance of a type + in types_to_prune, prune it from the copy, continue. + b. Otherwise, pass (prev, copy, and next) to reduce_fn. If reduce_fn: + I. returns an object: add it to the copy, replacing original + II. returns a tuple: insert it into the list, replacing original + III. returns None: prune it + + ** note that reduce_fn is always passed objects from the original + deep copy, not what prior calls return. See below for examples + 4. If an item is pruned, do not traverse its children + 5. Return the new deep copy. + + EXAMPLE 1 (filter): + >>> track = [A,B,C] + >>> def fn(prev_item, thing, next_item): + ... if prev_item.name == A: + ... return D # some new clip + ... else: + ... return thing + >>> filtered_with_sequence_context(track, fn) => [A,D,C] + + order of calls to fn: + fn(None, A, B) => A + fn(A, B, C) => D + fn(B, C, D) => C # !! note that it was passed B instead of D. + + EXAMPLE 2 (prune): + >>> track = [A,B,C] + >>> def fn(prev_item, thing, next_item): + ... if prev_item.name == A: + ... return None # prune the clip + ... else: + ... return thing + >>> filtered_with_sequence_context(track, fn) => [A,C] + + order of calls to fn: + fn(None, A, B) => A + fn(A, B, C) => None + fn(B, C, D) => C # !! note that it was passed B instead of D. + + EXAMPLE 3 (expand): + >>> def fn(prev_item, thing, next_item): + ... if prev_item.name == A: + ... return (D, E) # tuple of new clips + ... else: + ... return thing + >>> filtered_with_sequence_context(track, fn) => [A, D, E, C] + + the order of calls to fn will be: + fn(None, A, B) => A + fn(A, B, C) => (D, E) + fn(B, C, D) => C # !! note that it was passed B instead of D. + """ + + # deep copy everything + mutable_object = copy.deepcopy(root) + + prune_list = set() + + header_list = [mutable_object] + + if isinstance(mutable_object, schema.Timeline): + header_list.append(mutable_object.tracks) + + iter_list = header_list + list(mutable_object.each_child()) + + # expand to include prev, next when appropriate + expanded_iter_list = [] + for child in iter_list: + if _safe_parent(child) and isinstance(child.parent(), schema.Track): + prev_item, next_item = child.parent().neighbors_of(child) + expanded_iter_list.append((prev_item, child, next_item)) + else: + expanded_iter_list.append((None, child, None)) + + for prev_item, child, next_item in expanded_iter_list: + if _safe_parent(child) is not None and _is_in(child.parent(), prune_list): + prune_list.add(child) + continue + + parent = None + child_index = None + if _safe_parent(child) is not None: + child_index = child.parent().index(child) + parent = child.parent() + del child.parent()[child_index] + + # first try to prune + if types_to_prune and _isinstance_in(child, types_to_prune): + result = None + # finally call the user function + else: + result = reduce_fn(prev_item, child, next_item) + + if child is mutable_object: + mutable_object = result + + if result is None: + prune_list.add(child) + continue + + if type(result) is not tuple: + result = [result] + + if parent is not None: + parent[child_index:child_index] = result + + return mutable_object diff --git a/pype/vendor/python/python_2/opentimelineio/algorithms/stack_algo.py b/pype/vendor/python/python_2/opentimelineio/algorithms/stack_algo.py new file mode 100644 index 0000000000..cdb6424b46 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/algorithms/stack_algo.py @@ -0,0 +1,138 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +__doc__ = """ Algorithms for stack objects. """ + +import copy + +from .. import ( + schema, + opentime, +) +from . import ( + track_algo +) + + +def top_clip_at_time(in_stack, t): + """Return the topmost visible child that overlaps with time t. + + Example: + tr1: G1, A, G2 + tr2: [B------] + G1, and G2 are gaps, A and B are clips. + + If t is within A, a will be returned. If t is within G1 or G2, B will be + returned. + """ + + # ensure that it only runs on stacks + if not isinstance(in_stack, schema.Stack): + raise ValueError( + "Argument in_stack must be of type otio.schema.Stack, " + "not: '{}'".format( + type(in_stack) + ) + ) + + # build a range to use the `each_child`method. + search_range = opentime.TimeRange( + start_time=t, + # 0 duration so we are just sampling a point in time. + # XXX Should this duration be equal to the length of one sample? + # opentime.RationalTime(1, rate)? + duration=opentime.RationalTime(0, t.rate) + ) + + # walk through the children of the stack in reverse order. + for track in reversed(in_stack): + valid_results = [] + if hasattr(track, "each_child"): + valid_results = list( + c for c in track.each_clip(search_range, shallow_search=True) + if c.visible() + ) + + # XXX doesn't handle nested tracks/stacks at the moment + + for result in valid_results: + return result + + return None + + +def flatten_stack(in_stack): + """Flatten a Stack, or a list of Tracks, into a single Track. + Note that the 1st Track is the bottom one, and the last is the top. + """ + + flat_track = schema.Track() + flat_track.name = "Flattened" + + # map of track to track.range_of_all_children + range_track_map = {} + + def _get_next_item( + in_stack, + track_index=None, + trim_range=None + ): + if track_index is None: + # start with the top-most track + track_index = len(in_stack) - 1 + if track_index < 0: + # if you get to the bottom, you're done + return + + track = in_stack[track_index] + if trim_range is not None: + track = track_algo.track_trimmed_to_range(track, trim_range) + + track_map = range_track_map.get(track) + if track_map is None: + track_map = track.range_of_all_children() + range_track_map[track] = track_map + + for item in track: + if ( + item.visible() + or track_index == 0 + or isinstance(item, schema.Transition) + ): + yield item + else: + trim = track_map[item] + if trim_range is not None: + trim = opentime.TimeRange( + start_time=trim.start_time + trim_range.start_time, + duration=trim.duration + ) + track_map[item] = trim + for more in _get_next_item(in_stack, track_index - 1, trim): + yield more + + for item in _get_next_item(in_stack): + flat_track.append(copy.deepcopy(item)) + + return flat_track diff --git a/pype/vendor/python/python_2/opentimelineio/algorithms/timeline_algo.py b/pype/vendor/python/python_2/opentimelineio/algorithms/timeline_algo.py new file mode 100644 index 0000000000..bbb0ae6275 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/algorithms/timeline_algo.py @@ -0,0 +1,56 @@ +# +# Copyright 2019 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Algorithms for timeline objects.""" + +import copy + +from . import ( + track_algo +) + + +def timeline_trimmed_to_range(in_timeline, trim_range): + """Returns a new timeline that is a copy of the in_timeline, but with items + outside the trim_range removed and items on the ends trimmed to the + trim_range. Note that the timeline is never expanded, only shortened. + Please note that you could do nearly the same thing non-destructively by + just setting the Track's source_range but sometimes you want to really cut + away the stuff outside and that's what this function is meant for.""" + new_timeline = copy.deepcopy(in_timeline) + + for track_num, child_track in enumerate(in_timeline.tracks): + # @TODO: put the trim_range into the space of the tracks + # new_range = new_timeline.tracks.transformed_time_range( + # trim_range, + # child_track + # ) + + # trim the track and assign it to the new stack. + new_timeline.tracks[track_num] = track_algo.track_trimmed_to_range( + child_track, + trim_range + ) + + return new_timeline diff --git a/pype/vendor/python/python_2/opentimelineio/algorithms/track_algo.py b/pype/vendor/python/python_2/opentimelineio/algorithms/track_algo.py new file mode 100644 index 0000000000..8ac406f1d6 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/algorithms/track_algo.py @@ -0,0 +1,236 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Algorithms for track objects.""" + +import copy + +from .. import ( + schema, + exceptions, + opentime, +) + + +def track_trimmed_to_range(in_track, trim_range): + """Returns a new track that is a copy of the in_track, but with items + outside the trim_range removed and items on the ends trimmed to the + trim_range. Note that the track is never expanded, only shortened. + Please note that you could do nearly the same thing non-destructively by + just setting the Track's source_range but sometimes you want to really cut + away the stuff outside and that's what this function is meant for.""" + new_track = copy.deepcopy(in_track) + + track_map = new_track.range_of_all_children() + + # iterate backwards so we can delete items + for c, child in reversed(list(enumerate(new_track))): + child_range = track_map[child] + if not trim_range.overlaps(child_range): + # completely outside the trim range, so we discard it + del new_track[c] + elif trim_range.contains(child_range): + # completely contained, keep the whole thing + pass + else: + if isinstance(child, schema.Transition): + raise exceptions.CannotTrimTransitionsError( + "Cannot trim in the middle of a Transition." + ) + + # we need to clip the end(s) + child_source_range = child.trimmed_range() + + # should we trim the start? + if trim_range.start_time > child_range.start_time: + trim_amount = trim_range.start_time - child_range.start_time + child_source_range = opentime.TimeRange( + start_time=child_source_range.start_time + trim_amount, + duration=child_source_range.duration - trim_amount + + ) + + # should we trim the end? + trim_end = trim_range.end_time_exclusive() + child_end = child_range.end_time_exclusive() + if trim_end < child_end: + trim_amount = child_end - trim_end + child_source_range = opentime.TimeRange( + start_time=child_source_range.start_time, + duration=child_source_range.duration - trim_amount + + ) + + # set the new child's trims + child.source_range = child_source_range + + return new_track + + +def track_with_expanded_transitions(in_track): + """Expands transitions such that neighboring clips are trimmed into + regions of overlap. + + For example, if your track is: + Clip1, T, Clip2 + + will return: + Clip1', Clip1_t, T, Clip2_t, Clip2' + + Where Clip1' is the part of Clip1 not in the transition, Clip1_t is the + part inside the transition and so on. + """ + + result_track = [] + + seq_iter = iter(in_track) + prev_thing = None + thing = next(seq_iter, None) + next_thing = next(seq_iter, None) + + while thing is not None: + if isinstance(thing, schema.Transition): + result_track.append(_expand_transition(thing, in_track)) + else: + # not a transition, but might be trimmed by one before or after + # in the track + pre_transition = None + next_transition = None + + if isinstance(prev_thing, schema.Transition): + pre_transition = prev_thing + + if isinstance(next_thing, schema.Transition): + next_transition = next_thing + + result_track.append( + _trim_from_transitions( + thing, + pre=pre_transition, + post=next_transition + ) + ) + + # loop + prev_thing = thing + thing = next_thing + next_thing = next(seq_iter, None) + + return result_track + + +def _expand_transition(target_transition, from_track): + """ Expand transitions into the portions of pre-and-post clips that + overlap with the transition. + """ + + result = from_track.neighbors_of( + target_transition, + schema.NeighborGapPolicy.around_transitions + ) + + trx_duration = target_transition.in_offset + target_transition.out_offset + + # make copies of the before and after, and modify their in/out points + pre = copy.deepcopy(result.previous) + + if isinstance(pre, schema.Transition): + raise exceptions.TransitionFollowingATransitionError( + "cannot put two transitions next to each other in a track: " + "{}, {}".format( + pre, + target_transition + ) + ) + if target_transition.in_offset is None: + raise RuntimeError( + "in_offset is None on: {}".format(target_transition) + ) + + if target_transition.out_offset is None: + raise RuntimeError( + "out_offset is None on: {}".format(target_transition) + ) + + pre.name = (pre.name or "") + "_transition_pre" + + # ensure that pre.source_range is set, because it will get manipulated + tr = pre.trimmed_range() + + pre.source_range = opentime.TimeRange( + start_time=( + tr.end_time_exclusive() - target_transition.in_offset + ), + duration=trx_duration.rescaled_to( + tr.start_time + ) + ) + + post = copy.deepcopy(result.next) + if isinstance(post, schema.Transition): + raise exceptions.TransitionFollowingATransitionError( + "cannot put two transitions next to each other in a track: " + "{}, {}".format( + target_transition, + post + ) + ) + + post.name = (post.name or "") + "_transition_post" + + # ensure that post.source_range is set, because it will get manipulated + tr = post.trimmed_range() + + post.source_range = opentime.TimeRange( + start_time=( + tr.start_time - target_transition.in_offset + ).rescaled_to(tr.start_time), + duration=trx_duration.rescaled_to(tr.start_time) + ) + + return pre, target_transition, post + + +def _trim_from_transitions(thing, pre=None, post=None): + """ Trim clips next to transitions. """ + + result = copy.deepcopy(thing) + + # We might not have a source_range yet, + # We can trim to the computed trimmed_range to + # ensure we have something. + new_range = result.trimmed_range() + start_time = new_range.start_time + duration = new_range.duration + + if pre: + start_time += pre.out_offset + duration -= pre.out_offset + + if post: + duration -= post.in_offset + + result.source_range = opentime.TimeRange(start_time, duration) + + return result diff --git a/pype/vendor/python/python_2/opentimelineio/console/__init__.py b/pype/vendor/python/python_2/opentimelineio/console/__init__.py new file mode 100644 index 0000000000..e5f6e86988 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/__init__.py @@ -0,0 +1,40 @@ +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Console scripts for OpenTimelineIO + +.. moduleauthor:: Pixar Animation Studios +""" + +# flake8: noqa + +# in dependency hierarchy +from . import ( + otioconvert, + otiocat, + otiostat, + console_utils, + autogen_serialized_datamodel, +) + diff --git a/pype/vendor/python/python_2/opentimelineio/console/autogen_serialized_datamodel.py b/pype/vendor/python/python_2/opentimelineio/console/autogen_serialized_datamodel.py new file mode 100644 index 0000000000..046e8cbd1c --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/autogen_serialized_datamodel.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python +# +# Copyright 2019 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + + +"""Generates documentation of the serialized data model for OpenTimelineIO.""" + +import argparse +import inspect +import json +import tempfile +import sys + +try: + # python2 + import StringIO as io +except ImportError: + # python3 + import io + +import opentimelineio as otio + + +DOCUMENT_HEADER = """# OpenTimelineIO Serialized Data Documentation + +This document is a list of all the OpenTimelineIO classes that serialize to and +from JSON, omitting SchemaDef plugins. + +This document is automatically generated by running + docs/autogen_serialized_datamodel.py, or by running `make doc-model`. It is + part of the unit tests suite and should be updated whenever the schema changes. + If it needs to be updated, run: `make doc-model-update` and this file should be + regenerated. + +# Classes + +""" + +FIELDS_ONLY_HEADER = """# OpenTimelineIO Serialized Data Documentation + +This document is a list of all the OpenTimelineIO classes that serialize to and +from JSON, omitting plugins classes and docstrings. + +This document is automatically generated by running + docs/autogen_serialized_datamodel.py, or by running `make doc-model`. It is + part of the unit tests suite and should be updated whenever the schema changes. + If it needs to be updated, run: `make doc-model-update` and this file should be + regenerated. + +# Classes + +""" + +CLASS_HEADER_WITH_DOCS = """ +### {classname} + +*full module path*: `{modpath}` + +*documentation*: + +``` +{docstring} +``` + +parameters: +""" + +CLASS_HEADER_ONLY_FIELDS = """ +### {classname} + +parameters: +""" + +MODULE_HEADER = """ +## Module: {modname} +""" + +PROP_HEADER = """- *{propkey}*: {prophelp} +""" + +# @TODO: having type information here would be awesome +PROP_HEADER_NO_HELP = """- *{propkey}* +""" + +# three ways to try and get the property + docstring +PROP_FETCHERS = ( + lambda cl, k: inspect.getdoc(getattr(cl, k)), + lambda cl, k: inspect.getdoc(getattr(cl, "_" + k)), + lambda cl, k: inspect.getdoc(getattr(cl(), k)) and "" or "", +) + + +def _parsed_args(): + """ parse commandline arguments with argparse """ + + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + group = parser.add_mutually_exclusive_group() + group.add_argument( + "-d", + "--dryrun", + action="store_true", + default=False, + help="Dryrun mode - print out instead of perform actions" + ) + group.add_argument( + "-o", + "--output", + type=str, + default=None, + help="Update the baseline with the current version" + ) + + return parser.parse_args() + + +# things to skip +SKIP_CLASSES = [otio.core.SerializableObject, otio.core.UnknownSchema] +SKIP_KEYS = ["OTIO_SCHEMA"] # not data, just for the backing format +SKIP_MODULES = ["opentimelineio.schemadef"] # because these are plugins + + +def _generate_model_for_module(mod, classes, modules): + modules.add(mod) + + # fetch the classes from this module + serializeable_classes = [ + thing for thing in mod.__dict__.values() + if ( + inspect.isclass(thing) + and thing not in classes + and issubclass(thing, otio.core.SerializableObject) + or thing in ( + otio.opentime.RationalTime, + otio.opentime.TimeRange, + otio.opentime.TimeTransform, + ) + ) + ] + + # serialize/deserialize the classes to capture their serialized parameters + model = {} + for cl in serializeable_classes: + if cl in SKIP_CLASSES: + continue + + model[cl] = {} + field_dict = json.loads(otio.adapters.otio_json.write_to_string(cl())) + for k in field_dict.keys(): + if k in SKIP_KEYS: + continue + + for fetcher in PROP_FETCHERS: + try: + model[cl][k] = fetcher(cl, k) + break + except AttributeError: + pass + else: + sys.stderr.write("ERROR: could not fetch property: {}".format(k)) + + # Stashing the OTIO_SCHEMA back into the dictionary since the + # documentation uses this information in its header. + model[cl]["OTIO_SCHEMA"] = field_dict["OTIO_SCHEMA"] + + classes.update(model) + + # find new modules to recurse into + new_mods = sorted( + ( + thing for thing in mod.__dict__.values() + if ( + inspect.ismodule(thing) + and thing not in modules + and all(not thing.__name__.startswith(t) for t in SKIP_MODULES) + ) + ), + key=lambda mod: str(mod) + ) + + # recurse into the new modules and update the classes and modules values + [_generate_model_for_module(m, classes, modules) for m in new_mods] + + +def _generate_model(): + classes = {} + modules = set() + _generate_model_for_module(otio, classes, modules) + return classes + + +def _write_documentation(model): + md_with_helpstrings = io.StringIO() + md_only_fields = io.StringIO() + + md_with_helpstrings.write(DOCUMENT_HEADER) + md_only_fields.write(FIELDS_ONLY_HEADER) + + modules = {} + for cl in model: + modules.setdefault(cl.__module__, []).append(cl) + + CURRENT_MODULE = None + for module_list in sorted(modules): + this_mod = ".".join(module_list.split('.')[:2]) + if this_mod != CURRENT_MODULE: + CURRENT_MODULE = this_mod + md_with_helpstrings.write(MODULE_HEADER.format(modname=this_mod)) + md_only_fields.write(MODULE_HEADER.format(modname=this_mod)) + + # because these are classes, they need to sort on their stringified + # names + for cl in sorted(modules[module_list], key=lambda cl: str(cl)): + modname = inspect.getmodule(cl).__name__ + label = model[cl]["OTIO_SCHEMA"] + md_with_helpstrings.write( + CLASS_HEADER_WITH_DOCS.format( + classname=label, + modpath=modname + "." + cl.__name__, + docstring=cl.__doc__ + ) + ) + md_only_fields.write( + CLASS_HEADER_ONLY_FIELDS.format( + classname=label, + ) + ) + + for key, helpstr in sorted(model[cl].items()): + if key in SKIP_KEYS: + continue + md_with_helpstrings.write( + PROP_HEADER.format(propkey=key, prophelp=helpstr) + ) + md_only_fields.write( + PROP_HEADER_NO_HELP.format(propkey=key) + ) + + return md_with_helpstrings.getvalue(), md_only_fields.getvalue() + + +def main(): + """ main entry point """ + args = _parsed_args() + with_docs, without_docs = generate_and_write_documentation() + + # print it out somewhere + if args.dryrun: + print(with_docs) + return + + output = args.output + if not output: + output = tempfile.NamedTemporaryFile( + 'w', + suffix="otio_serialized_schema.md", + delete=False + ).name + + with open(output, 'w') as fo: + fo.write(with_docs) + + # write version without docstrings + prefix, suffix = output.rsplit('.', 1) + output_only_fields = prefix + "-only-fields." + suffix + + with open(output_only_fields, 'w') as fo: + fo.write(without_docs) + + print("wrote documentation to {} and {}".format(output, output_only_fields)) + + +def generate_and_write_documentation(): + model = _generate_model() + return _write_documentation(model) + + +if __name__ == '__main__': + main() diff --git a/pype/vendor/python/python_2/opentimelineio/console/console_utils.py b/pype/vendor/python/python_2/opentimelineio/console/console_utils.py new file mode 100644 index 0000000000..9c659433e3 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/console_utils.py @@ -0,0 +1,72 @@ +# +# Copyright 2019 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +import ast + +from .. import ( + media_linker, +) + +"""Utilities for OpenTimelineIO commandline modules.""" + + +def arg_list_to_map(arg_list, label): + """ + Convert an argument of the form -A foo=bar from the parsed result to a map. + """ + + argument_map = {} + for pair in arg_list: + if '=' not in pair: + raise ValueError( + "error: {} arguments must be in the form key=value" + " got: {}".format(label, pair) + ) + + key, val = pair.split('=', 1) # only split on the 1st '=' + try: + # Sometimes we need to pass a bool, int, list, etc. + parsed_value = ast.literal_eval(val) + except (ValueError, SyntaxError): + # Fall back to a simple string + parsed_value = val + argument_map[key] = parsed_value + + return argument_map + + +def media_linker_name(ml_name_arg): + """ + Parse commandline arguments for the media linker, which can be not set + (fall back to default), "" or "none" (don't link media) or the name of a + media linker to use. + """ + if ml_name_arg.lower() == 'default': + media_linker_name = media_linker.MediaLinkingPolicy.ForceDefaultLinker + elif ml_name_arg.lower() in ['none', '']: + media_linker_name = media_linker.MediaLinkingPolicy.DoNotLinkMedia + else: + media_linker_name = ml_name_arg + + return media_linker_name diff --git a/pype/vendor/python/python_2/opentimelineio/console/otiocat.py b/pype/vendor/python/python_2/opentimelineio/console/otiocat.py new file mode 100644 index 0000000000..9513144512 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/otiocat.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Print the contents of an OTIO file to stdout.""" + +import argparse +import sys + +import opentimelineio as otio + + +def _parsed_args(): + """ parse commandline arguments with argparse """ + + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument( + 'filepath', + type=str, + nargs='+', + help='files to print the contents of' + ) + parser.add_argument( + '-a', + '--adapter-arg', + type=str, + default=[], + action='append', + help='Extra arguments to be passed to input adapter in the form of ' + 'key=value. Values are strings, numbers or Python literals: True, ' + 'False, etc. Can be used multiple times: -a burrito="bar" -a taco=12.' + ) + parser.add_argument( + '-m', + '--media-linker', + type=str, + default="Default", + help=( + "Specify a media linker. 'Default' means use the " + "$OTIO_DEFAULT_MEDIA_LINKER if set, 'None' or '' means explicitly " + "disable the linker, and anything else is interpreted as the name" + " of the media linker to use." + ) + ) + parser.add_argument( + '-M', + '--media-linker-arg', + type=str, + default=[], + action='append', + help='Extra arguments to be passed to the media linker in the form of ' + 'key=value. Values are strings, numbers or Python literals: True, ' + 'False, etc. Can be used multiple times: -M burrito="bar" -M taco=12.' + ) + + return parser.parse_args() + + +def _otio_compatible_file_to_json_string( + fpath, + media_linker_name, + media_linker_argument_map, + adapter_argument_map +): + """Read the file at fpath with the default otio adapter and return the json + as a string. + """ + + adapter = otio.adapters.from_name("otio_json") + return adapter.write_to_string( + otio.adapters.read_from_file( + fpath, + media_linker_name=media_linker_name, + media_linker_argument_map=media_linker_argument_map, + **adapter_argument_map + ) + ) + + +def main(): + """Parse arguments and call _otio_compatible_file_to_json_string.""" + + args = _parsed_args() + + media_linker_name = otio.console.console_utils.media_linker_name( + args.media_linker + ) + + try: + read_adapter_arg_map = otio.console.console_utils.arg_list_to_map( + args.adapter_arg, + "adapter" + ) + media_linker_argument_map = otio.console.console_utils.arg_list_to_map( + args.media_linker_arg, + "media linker" + ) + except ValueError as exc: + sys.stderr.write("\n" + str(exc) + "\n") + sys.exit(1) + + for fpath in args.filepath: + print( + _otio_compatible_file_to_json_string( + fpath, + media_linker_name, + media_linker_argument_map, + read_adapter_arg_map + ) + ) + + +if __name__ == '__main__': + main() diff --git a/pype/vendor/python/python_2/opentimelineio/console/otioconvert.py b/pype/vendor/python/python_2/opentimelineio/console/otioconvert.py new file mode 100644 index 0000000000..9d45a0fcf4 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/otioconvert.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +import argparse +import sys +import copy + +import opentimelineio as otio + +__doc__ = """ Python wrapper around OTIO to convert timeline files between \ +formats. + +Available adapters: {} +""".format(otio.adapters.available_adapter_names()) + + +def _parsed_args(): + """ parse commandline arguments with argparse """ + + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument( + '-i', + '--input', + type=str, + required=True, + help='path to input file', + ) + parser.add_argument( + '-o', + '--output', + type=str, + required=True, + help='path to output file', + ) + parser.add_argument( + '-I', + '--input-adapter', + type=str, + default=None, + help="Explicitly use this adapter for reading the input file", + ) + parser.add_argument( + '-O', + '--output-adapter', + type=str, + default=None, + help="Explicitly use this adapter for writing the output file", + ) + parser.add_argument( + '-T', + '--tracks', + type=str, + default=None, + help="Pick one or more tracks, by 0-based index, separated by commas.", + ) + parser.add_argument( + '-m', + '--media-linker', + type=str, + default="Default", + help=( + "Specify a media linker. 'Default' means use the " + "$OTIO_DEFAULT_MEDIA_LINKER if set, 'None' or '' means explicitly " + "disable the linker, and anything else is interpreted as the name" + " of the media linker to use." + ) + ) + parser.add_argument( + '-M', + '--media-linker-arg', + type=str, + default=[], + action='append', + help='Extra arguments to be passed to the media linker in the form of ' + 'key=value. Values are strings, numbers or Python literals: True, ' + 'False, etc. Can be used multiple times: -M burrito="bar" -M taco=12.' + ) + parser.add_argument( + '-a', + '--adapter-arg', + type=str, + default=[], + action='append', + help='Extra arguments to be passed to input adapter in the form of ' + 'key=value. Values are strings, numbers or Python literals: True, ' + 'False, etc. Can be used multiple times: -a burrito="bar" -a taco=12.' + ) + parser.add_argument( + '-A', + '--output-adapter-arg', + type=str, + default=[], + action='append', + help='Extra arguments to be passed to output adapter in the form of ' + 'key=value. Values are strings, numbers or Python literals: True, ' + 'False, etc. Can be used multiple times: -A burrito="bar" -A taco=12.' + ) + trim_args = parser.add_argument_group( + title="Trim Arguments", + description="Arguments that allow you to trim the OTIO file." + ) + trim_args.add_argument( + '--begin', + type=str, + default=None, + help=( + "Trim out everything in the timeline before this time, in the " + "global time frame of the timeline. Argument should be in the form" + ' "VALUE,RATE", eg: --begin "10,24". Requires --end argument.' + ), + ) + trim_args.add_argument( + '--end', + type=str, + default=None, + help=( + "Trim out everything in the timeline after this time, in the " + "global time frame of the timeline. Argument should be in the form" + ' "VALUE,RATE", eg: --begin "10,24". Requires --begin argument.' + ), + ) + + result = parser.parse_args() + + if result.begin is not None and result.end is None: + parser.error("--begin requires --end.") + if result.end is not None and result.begin is None: + parser.error("--end requires --begin.") + + if result.begin is not None: + try: + value, rate = result.begin.split(",") + result.begin = otio.opentime.RationalTime(float(value), float(rate)) + except ValueError: + parser.error( + "--begin argument needs to be of the form: VALUE,RATE where " + "VALUE is the (float) time value of the resulting RationalTime " + "and RATE is the (float) time rate of the resulting RationalTime," + " not '{}'".format(result.begin) + ) + + if result.end is not None: + try: + value, rate = result.end.split(",") + result.end = otio.opentime.RationalTime(float(value), float(rate)) + except ValueError: + parser.error( + "--end argument needs to be of the form: VALUE,RATE where " + "VALUE is the (float) time value of the resulting RationalTime " + "and RATE is the (float) time rate of the resulting RationalTime," + " not '{}'".format(result.begin) + ) + + return result + + +def main(): + """Parse arguments and convert the files.""" + + args = _parsed_args() + + in_adapter = args.input_adapter + if in_adapter is None: + in_adapter = otio.adapters.from_filepath(args.input).name + + out_adapter = args.output_adapter + if out_adapter is None: + out_adapter = otio.adapters.from_filepath(args.output).name + + media_linker_name = otio.console.console_utils.media_linker_name( + args.media_linker + ) + + try: + read_adapter_arg_map = otio.console.console_utils.arg_list_to_map( + args.adapter_arg, + "input adapter" + ) + ml_args = otio.console.console_utils.arg_list_to_map( + args.media_linker_arg, + "media linker" + ) + except ValueError as exc: + sys.stderr.write("\n" + str(exc) + "\n") + sys.exit(1) + + result_tl = otio.adapters.read_from_file( + args.input, + in_adapter, + media_linker_name=media_linker_name, + media_linker_argument_map=ml_args, + **read_adapter_arg_map + ) + + if args.tracks: + result_tracks = copy.deepcopy(otio.schema.Stack()) + del result_tracks[:] + for track in args.tracks.split(","): + tr = result_tl.tracks[int(track)] + del result_tl.tracks[int(track)] + print("track {0} is of kind: '{1}'".format(track, tr.kind)) + result_tracks.append(tr) + result_tl.tracks = result_tracks + + # handle trim arguments + if args.begin is not None and args.end is not None: + result_tl = otio.algorithms.timeline_trimmed_to_range( + result_tl, + otio.opentime.range_from_start_end_time(args.begin, args.end) + ) + + try: + write_adapter_arg_map = otio.console.console_utils.arg_list_to_map( + args.output_adapter_arg, + "output adapter" + ) + except ValueError as exc: + sys.stderr.write("\n" + str(exc) + "\n") + sys.exit(1) + + otio.adapters.write_to_file( + result_tl, + args.output, + out_adapter, + **write_adapter_arg_map + ) + + +if __name__ == '__main__': + try: + main() + except otio.exceptions.OTIOError as err: + sys.stderr.write("ERROR: " + str(err) + "\n") + sys.exit(1) diff --git a/pype/vendor/python/python_2/opentimelineio/console/otiostat.py b/pype/vendor/python/python_2/opentimelineio/console/otiostat.py new file mode 100644 index 0000000000..9cd554727a --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/console/otiostat.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Print statistics about the otio file, including validation information.""" + +import argparse +import sys + +import opentimelineio as otio + + +def _parsed_args(): + """ parse commandline arguments with argparse """ + + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument( + 'filepath', + type=str, + nargs='+', + help='files to operate on' + ) + + return parser.parse_args() + + +TESTS = [] + + +def stat_check(name): + def real_stat_check(fn): + TESTS.append((name, fn)) + return fn + return real_stat_check + + +@stat_check("parsed") +def _did_parse(input): + return input and True or False + + +@stat_check("top level object") +def _top_level_object(input): + return input._serializable_label + + +@stat_check("number of tracks") +def _num_tracks(input): + try: + return len(input.tracks) + except AttributeError: + return 0 + + +@stat_check("Tracks are the same length") +def _equal_length_tracks(tl): + if not tl.tracks: + return True + for i, track in enumerate(tl.tracks): + if track.duration() != tl.tracks[0].duration(): + raise RuntimeError( + "track {} is not the same duration as the other tracks." + " Track {} duration, vs: {}".format( + i, + track.duration(), + tl.tracks[0].duration() + ) + ) + return True + + +@stat_check("deepest nesting") +def _deepest_nesting(input): + def depth(parent): + if not isinstance(parent, otio.core.Composition): + return 1 + d = 0 + for child in parent: + d = max(d, depth(child) + 1) + return d + if isinstance(input, otio.schema.Timeline): + return depth(input.tracks) + 1 + else: + return depth(input) + + +@stat_check("number of clips") +def _num_clips(input): + return len(list(input.each_clip())) + + +@stat_check("total duration") +def _total_duration(input): + try: + return input.tracks.duration() + except AttributeError: + return "n/a" + + +@stat_check("total duration in timecode") +def _total_duration_timecode(input): + try: + d = input.tracks.duration() + return otio.opentime.to_timecode(d, d.rate) + except AttributeError: + return "n/a" + + +@stat_check("top level rate") +def _top_level_rate(input): + try: + return input.tracks.duration().rate + except AttributeError: + return "n/a" + + +@stat_check("clips with cdl data") +def _clips_with_cdl_data(input): + return len(list(c for c in input.each_clip() if 'cdl' in c.metadata)) + + +@stat_check("Tracks with non standard types") +def _sequences_with_non_standard_types(input): + return len( + list( + c + for c in input.each_child(descended_from_type=otio.schema.Track) + if c.kind not in (otio.schema.TrackKind.__dict__) + ) + ) + + +def _stat_otio(input_otio): + for (test, testfunc) in TESTS: + try: + print("{}: {}".format(test, testfunc(input_otio))) + except (otio.exceptions.OTIOError) as e: + sys.stderr.write( + "There was an OTIO Error: " + " {}\n".format(e), + ) + continue + except (Exception) as e: + sys.stderr.write("There was a system error: {}\n".format(e)) + continue + + +def main(): + """ main entry point """ + args = _parsed_args() + + for fp in args.filepath: + try: + parsed_otio = otio.adapters.read_from_file(fp) + except (otio.exceptions.OTIOError) as e: + sys.stderr.write( + "The file did not successfully parse, with error:" + " {}\n".format(e), + ) + continue + except (Exception) as e: + sys.stderr.write("There was a system error: {}\n".format(e)) + continue + + _stat_otio(parsed_otio) + + +if __name__ == '__main__': + main() diff --git a/pype/vendor/python/python_2/opentimelineio/core/__init__.py b/pype/vendor/python/python_2/opentimelineio/core/__init__.py new file mode 100644 index 0000000000..ac5c0bbcc0 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/__init__.py @@ -0,0 +1,67 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Internal implementation details of OpenTimelineIO.""" + +# flake8: noqa + +from . import ( + serializable_object +) +from .serializable_object import ( + SerializableObject, + serializable_field, + deprecated_field, +) +from .composable import ( + Composable +) +from .item import ( + Item +) +from . import composition +from .composition import ( + Composition, +) +from . import type_registry +from .type_registry import ( + register_type, + upgrade_function_for, + schema_name_from_label, + schema_version_from_label, + instance_from_schema, +) +from .json_serializer import ( + serialize_json_to_string, + serialize_json_to_file, + deserialize_json_from_string, + deserialize_json_from_file, +) +from .media_reference import ( + MediaReference, +) +from . import unknown_schema +from .unknown_schema import ( + UnknownSchema +) diff --git a/pype/vendor/python/python_2/opentimelineio/core/composable.py b/pype/vendor/python/python_2/opentimelineio/core/composable.py new file mode 100644 index 0000000000..78c7fba349 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/composable.py @@ -0,0 +1,141 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Composable class definition. + +An object that can be composed by tracks. +""" + +import weakref + +from . import serializable_object +from . import type_registry + +import copy + + +@type_registry.register_type +class Composable(serializable_object.SerializableObject): + """An object that can be composed by tracks. + + Base class of: + Item + Transition + """ + + name = serializable_object.serializable_field( + "name", + doc="Composable name." + ) + metadata = serializable_object.serializable_field( + "metadata", + doc="Metadata dictionary for this Composable." + ) + + _serializable_label = "Composable.1" + _class_path = "core.Composable" + + def __init__(self, name=None, metadata=None): + super(Composable, self).__init__() + self._parent = None + + # initialize the serializable fields + self.name = name + self.metadata = copy.deepcopy(metadata) if metadata else {} + + @staticmethod + def visible(): + """Return the visibility of the Composable. By default True.""" + + return False + + @staticmethod + def overlapping(): + """Return whether an Item is overlapping. By default False.""" + + return False + + # @{ functions to express the composable hierarchy + def _root_parent(self): + return ([self] + self._ancestors())[-1] + + def _ancestors(self): + ancestors = [] + seqi = self + while seqi.parent() is not None: + seqi = seqi.parent() + ancestors.append(seqi) + return ancestors + + def parent(self): + """Return the parent Composable, or None if self has no parent.""" + + return self._parent() if self._parent is not None else None + + def _set_parent(self, new_parent): + if new_parent is not None and self.parent() is not None: + raise ValueError( + "Composable named '{}' is already in a composition named '{}'," + " remove from previous parent before adding to new one." + " Composable: {}, Composition: {}".format( + self.name, + self.parent() is not None and self.parent().name or None, + self, + self.parent() + ) + ) + self._parent = weakref.ref(new_parent) if new_parent is not None else None + + def is_parent_of(self, other): + """Returns true if self is a parent or ancestor of other.""" + + visited = set([]) + while other.parent() is not None and other.parent() not in visited: + if other.parent() is self: + return True + visited.add(other) + other = other.parent() + + return False + + # @} + + def __repr__(self): + return ( + "otio.{}(" + "name={}, " + "metadata={}" + ")".format( + self._class_path, + repr(self.name), + repr(self.metadata) + ) + ) + + def __str__(self): + return "{}({}, {})".format( + self._class_path.split('.')[-1], + self.name, + str(self.metadata) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/core/composition.py b/pype/vendor/python/python_2/opentimelineio/core/composition.py new file mode 100644 index 0000000000..4da5a4b091 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/composition.py @@ -0,0 +1,718 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Composition base class. An object that contains `Items`.""" + +import collections + +from . import ( + serializable_object, + type_registry, + item, + composable, +) + +from .. import ( + opentime, + exceptions +) + + +def _bisect_right( + seq, + tgt, + key_func, + lower_search_bound=0, + upper_search_bound=None +): + """Return the index of the last item in seq such that all e in seq[:index] + have key_func(e) <= tgt, and all e in seq[index:] have key_func(e) > tgt. + + Thus, seq.insert(index, value) will insert value after the rightmost item + such that meets the above condition. + + lower_search_bound and upper_search_bound bound the slice to be searched. + + Assumes that seq is already sorted. + """ + + if lower_search_bound < 0: + raise ValueError('lower_search_bound must be non-negative') + + if upper_search_bound is None: + upper_search_bound = len(seq) + + while lower_search_bound < upper_search_bound: + midpoint_index = (lower_search_bound + upper_search_bound) // 2 + + if tgt < key_func(seq[midpoint_index]): + upper_search_bound = midpoint_index + else: + lower_search_bound = midpoint_index + 1 + + return lower_search_bound + + +def _bisect_left( + seq, + tgt, + key_func, + lower_search_bound=0, + upper_search_bound=None +): + """Return the index of the last item in seq such that all e in seq[:index] + have key_func(e) < tgt, and all e in seq[index:] have key_func(e) >= tgt. + + Thus, seq.insert(index, value) will insert value before the leftmost item + such that meets the above condition. + + lower_search_bound and upper_search_bound bound the slice to be searched. + + Assumes that seq is already sorted. + """ + + if lower_search_bound < 0: + raise ValueError('lower_search_bound must be non-negative') + + if upper_search_bound is None: + upper_search_bound = len(seq) + + while lower_search_bound < upper_search_bound: + midpoint_index = (lower_search_bound + upper_search_bound) // 2 + + if key_func(seq[midpoint_index]) < tgt: + lower_search_bound = midpoint_index + 1 + else: + upper_search_bound = midpoint_index + + return lower_search_bound + + +@type_registry.register_type +class Composition(item.Item, collections.MutableSequence): + """Base class for an OTIO Item that contains other Items. + + Should be subclassed (for example by Track and Stack), not used + directly. + """ + + _serializable_label = "Composition.1" + _composition_kind = "Composition" + _modname = "core" + _composable_base_class = composable.Composable + + def __init__( + self, + name=None, + children=None, + source_range=None, + markers=None, + effects=None, + metadata=None + ): + item.Item.__init__( + self, + name=name, + source_range=source_range, + markers=markers, + effects=effects, + metadata=metadata + ) + collections.MutableSequence.__init__(self) + + # Because we know that all children are unique, we store a set + # of all the children as well to speed up __contain__ checks. + self._child_lookup = set() + + self._children = [] + if children: + # cannot simply set ._children to children since __setitem__ runs + # extra logic (assigning ._parent pointers) and populates the + # internal membership set _child_lookup. + self.extend(children) + + _children = serializable_object.serializable_field( + "children", + list, + "Items contained by this composition." + ) + + @property + def composition_kind(self): + """Returns a label specifying the kind of composition.""" + + return self._composition_kind + + def __str__(self): + return "{}({}, {}, {}, {})".format( + self._composition_kind, + str(self.name), + str(self._children), + str(self.source_range), + str(self.metadata) + ) + + def __repr__(self): + return ( + "otio.{}.{}(" + "name={}, " + "children={}, " + "source_range={}, " + "metadata={}" + ")".format( + self._modname, + self._composition_kind, + repr(self.name), + repr(self._children), + repr(self.source_range), + repr(self.metadata) + ) + ) + + transform = serializable_object.deprecated_field() + + def child_at_time( + self, + search_time, + shallow_search=False, + ): + """Return the child that overlaps with time search_time. + + search_time is in the space of self. + + If shallow_search is false, will recurse into compositions. + """ + + range_map = self.range_of_all_children() + + # find the first item whose end_time_exclusive is after the + first_inside_range = _bisect_left( + seq=self._children, + tgt=search_time, + key_func=lambda child: range_map[child].end_time_exclusive(), + ) + + # find the last item whose start_time is before the + last_in_range = _bisect_right( + seq=self._children, + tgt=search_time, + key_func=lambda child: range_map[child].start_time, + lower_search_bound=first_inside_range, + ) + + # limit the search to children who are in the search_range + possible_matches = self._children[first_inside_range:last_in_range] + + result = None + for thing in possible_matches: + if range_map[thing].overlaps(search_time): + result = thing + break + + # if the search cannot or should not continue + if ( + result is None + or shallow_search + or not hasattr(result, "child_at_time") + ): + return result + + # before you recurse, you have to transform the time into the + # space of the child + child_search_time = self.transformed_time(search_time, result) + + return result.child_at_time(child_search_time, shallow_search) + + def each_child( + self, + search_range=None, + descended_from_type=composable.Composable, + shallow_search=False, + ): + """ Generator that returns each child contained in the composition in + the order in which it is found. + + Arguments: + search_range: if specified, only children whose range overlaps with + the search range will be yielded. + descended_from_type: if specified, only children who are a + descendent of the descended_from_type will be yielded. + shallow_search: if True, will only search children of self, not + and not recurse into children of children. + """ + if search_range: + range_map = self.range_of_all_children() + + # find the first item whose end_time_inclusive is after the + # start_time of the search range + first_inside_range = _bisect_left( + seq=self._children, + tgt=search_range.start_time, + key_func=lambda child: range_map[child].end_time_inclusive(), + ) + + # find the last item whose start_time is before the + # end_time_inclusive of the search_range + last_in_range = _bisect_right( + seq=self._children, + tgt=search_range.end_time_inclusive(), + key_func=lambda child: range_map[child].start_time, + lower_search_bound=first_inside_range, + ) + + # limit the search to children who are in the search_range + children = self._children[first_inside_range:last_in_range] + else: + # otherwise search all the children + children = self._children + + for child in children: + # filter out children who are not descended from the specified type + # shortcut the isinstance if descended_from_type is composable + # (since all objects in compositions are already composables) + is_descendant = descended_from_type == composable.Composable + if is_descendant or isinstance(child, descended_from_type): + yield child + + # if not a shallow_search, for children that are compositions, + # recurse into their children + if not shallow_search and hasattr(child, "each_child"): + + if search_range is not None: + search_range = self.transformed_time_range(search_range, child) + + for valid_child in child.each_child( + search_range, + descended_from_type, + shallow_search + ): + yield valid_child + + def range_of_child_at_index(self, index): + """Return the range of a child item in the time range of this + composition. + + For example, with a track: + [ClipA][ClipB][ClipC] + + The self.range_of_child_at_index(2) will return: + TimeRange(ClipA.duration + ClipB.duration, ClipC.duration) + + To be implemented by subclass of Composition. + """ + + raise NotImplementedError + + def trimmed_range_of_child_at_index(self, index): + """Return the trimmed range of the child item at index in the time + range of this composition. + + For example, with a track: + + [ ] + + [ClipA][ClipB][ClipC] + + The range of index 2 (ClipC) will be just like + range_of_child_at_index() but trimmed based on this Composition's + source_range. + + To be implemented by child. + """ + + raise NotImplementedError + + def range_of_all_children(self): + """Return a dict mapping children to their range in this object.""" + + raise NotImplementedError + + def __copy__(self): + result = super(Composition, self).__copy__() + + # Children are *not* copied with a shallow copy since the meaning is + # ambiguous - they have a parent pointer which would need to be flipped + # or they would need to be copied, which implies a deepcopy(). + # + # This follows from the python documentation on copy/deepcopy: + # https://docs.python.org/2/library/copy.html + # + # """ + # - A shallow copy constructs a new compound object and then (to the + # extent possible) inserts references into it to the objects found in + # the original. + # - A deep copy constructs a new compound object and then, recursively, + # inserts copies into it of the objects found in the original. + # """ + result._children = [] + + return result + + def __deepcopy__(self, md): + result = super(Composition, self).__deepcopy__(md) + + # deepcopy should have already copied the children, so only parent + # pointers need to be updated. + [c._set_parent(result) for c in result._children] + + # we also need to reconstruct the membership set of _child_lookup. + result._child_lookup.update(result._children) + + return result + + def _path_to_child(self, child): + if not isinstance(child, composable.Composable): + raise TypeError( + "An object child of 'Composable' is required," + " not type '{}'".format( + type(child) + ) + ) + + current = child + parents = [] + + while(current is not self): + try: + current = current.parent() + except AttributeError: + raise exceptions.NotAChildError( + "Item '{}' is not a child of '{}'.".format(child, self) + ) + + parents.append(current) + + return parents + + def range_of_child(self, child, reference_space=None): + """The range of the child in relation to another item + (reference_space), not trimmed based on this + composition's source_range. + + Note that reference_space must be in the same timeline as self. + + For example: + + | [-----] | seq + + [-----------------] Clip A + + If ClipA has duration 17, and seq has source_range: 5, duration 15, + seq.range_of_child(Clip A) will return (0, 17) + ignoring the source range of seq. + + To get the range of the child with the source_range applied, use the + trimmed_range_of_child() method. + """ + + if not reference_space: + reference_space = self + + parents = self._path_to_child(child) + + current = child + result_range = None + + for parent in parents: + index = parent.index(current) + parent_range = parent.range_of_child_at_index(index) + + if not result_range: + result_range = parent_range + current = parent + continue + + result_range = opentime.TimeRange( + start_time=result_range.start_time + parent_range.start_time, + duration=result_range.duration + ) + current = parent + + if reference_space is not self: + result_range = self.transformed_time_range( + result_range, + reference_space + ) + + return result_range + + def handles_of_child(self, child): + """If media beyond the ends of this child are visible due to adjacent + Transitions (only applicable in a Track) then this will return the + head and tail offsets as a tuple of RationalTime objects. If no handles + are present on either side, then None is returned instead of a + RationalTime. + + Example usage: + >>> head, tail = track.handles_of_child(clip) + >>> if head: + ... print('Do something') + >>> if tail: + ... print('Do something else') + """ + return (None, None) + + def trimmed_range_of_child(self, child, reference_space=None): + """Get range of the child in reference_space coordinates, after the + self.source_range is applied. + + Example + | [-----] | seq + [-----------------] Clip A + + If ClipA has duration 17, and seq has source_range: 5, duration 10, + seq.trimmed_range_of_child(Clip A) will return (5, 10) + Which is trimming the range according to the source_range of seq. + + To get the range of the child without the source_range applied, use the + range_of_child() method. + + Another example + | [-----] | seq source range starts on frame 4 and goes to frame 8 + [ClipA][ClipB] (each 6 frames long) + + >>> seq.range_of_child(CLipA) + 0, duration 6 + >>> seq.trimmed_range_of_child(ClipA): + 4, duration 2 + """ + + if not reference_space: + reference_space = self + + if not reference_space == self: + raise NotImplementedError + + parents = self._path_to_child(child) + + current = child + result_range = None + + for parent in parents: + index = parent.index(current) + parent_range = parent.trimmed_range_of_child_at_index(index) + + if not result_range: + result_range = parent_range + current = parent + continue + + result_range.start_time += parent_range.start_time + current = parent + + if not self.source_range or not result_range: + return result_range + + new_start_time = max( + self.source_range.start_time, + result_range.start_time + ) + + # trimmed out + if new_start_time >= result_range.end_time_exclusive(): + return None + + # compute duration + new_duration = min( + result_range.end_time_exclusive(), + self.source_range.end_time_exclusive() + ) - new_start_time + + if new_duration.value < 0: + return None + + return opentime.TimeRange(new_start_time, new_duration) + + def trim_child_range(self, child_range): + if not self.source_range: + return child_range + + # cropped out entirely + past_end_time = self.source_range.start_time >= child_range.end_time_exclusive() + before_start_time = \ + self.source_range.end_time_exclusive() <= child_range.start_time + + if past_end_time or before_start_time: + return None + + if child_range.start_time < self.source_range.start_time: + child_range = opentime.range_from_start_end_time( + self.source_range.start_time, + child_range.end_time_exclusive() + ) + + if ( + child_range.end_time_exclusive() > + self.source_range.end_time_exclusive() + ): + child_range = opentime.range_from_start_end_time( + child_range.start_time, + self.source_range.end_time_exclusive() + ) + + return child_range + + # @{ SerializableObject override. + def _update(self, d): + """Like the dictionary .update() method. + + Update the data dictionary of this SerializableObject with the .data + of d if d is a SerializableObject or if d is a dictionary, d itself. + """ + + # use the parent update function + super(Composition, self)._update(d) + + # ...except for the 'children' field, which needs to run through the + # insert method so that _parent pointers are correctly set on children. + self._children = [] + self.extend(d.get('children', [])) + # @} + + # @{ collections.MutableSequence implementation + def __getitem__(self, item): + return self._children[item] + + def _setitem_slice(self, key, value): + set_value = set(value) + + # check if any members in the new slice are repeated + if len(set_value) != len(value): + raise ValueError( + "Instancing not allowed in Compositions, {} contains repeated" + " items.".format(value) + ) + + old = self._children[key] + if old: + set_old = set(old) + set_outside_old = set(self._children).difference(set_old) + + isect = set_outside_old.intersection(set_value) + if isect: + raise ValueError( + "Attempting to insert duplicates of items {} already " + "present in container, instancing not allowed in " + "Compositions".format(isect) + ) + + # update old parent + for val in old: + val._set_parent(None) + self._child_lookup.remove(val) + + # insert into _children + self._children[key] = value + + # update new parent + if value: + for val in value: + val._set_parent(self) + self._child_lookup.add(val) + + def __setitem__(self, key, value): + # fetch the current thing at that index/slice + old = self._children[key] + + # in the case of key being a slice, old and value are both sequences + if old is value: + return + + if isinstance(key, slice): + return self._setitem_slice(key, value) + + if value in self: + raise ValueError( + "Composable {} already present in this container, instancing" + " not allowed in otio compositions.".format(value) + ) + + # unset the old child's parent and delete the membership entry. + if old is not None: + old._set_parent(None) + self._child_lookup.remove(old) + + # put it into our list of children + self._children[key] = value + + # set the new parent + if value is not None: + value._set_parent(self) + + # put it into our membership tracking set + self._child_lookup.add(value) + + def insert(self, index, item): + """Insert an item into the composition at location `index`.""" + + if not isinstance(item, self._composable_base_class): + raise TypeError( + "Not allowed to insert an object of type {0} into a {1}, only" + " objects descending from {2}. Tried to insert: {3}".format( + type(item), + type(self), + self._composable_base_class, + str(item) + ) + ) + + if item in self: + raise ValueError( + "Composable {} already present in this container, instancing" + " not allowed in otio compositions.".format(item) + ) + + # set the item's parent and add it to our membership tracking and list + # of children + item._set_parent(self) + self._child_lookup.add(item) + self._children.insert(index, item) + + def __contains__(self, item): + """Use our internal membership tracking set to speed up searches.""" + return item in self._child_lookup + + def __len__(self): + """The len() of a Composition is the # of children in it. + Note that this also means that a Composition with no children + is considered False, so take care to test for "if foo is not None" + versus just "if foo" when the difference matters.""" + return len(self._children) + + def __delitem__(self, key): + # grab the old value + old = self._children[key] + + # remove it from the membership tracking set and clear parent + if old is not None: + if isinstance(key, slice): + for val in old: + self._child_lookup.remove(val) + val._set_parent(None) + else: + self._child_lookup.remove(old) + old._set_parent(None) + + # remove it from our list of children + del self._children[key] diff --git a/pype/vendor/python/python_2/opentimelineio/core/item.py b/pype/vendor/python/python_2/opentimelineio/core/item.py new file mode 100644 index 0000000000..7e035a3a9e --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/item.py @@ -0,0 +1,243 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of the Item base class. OTIO Objects that contain media.""" + +import copy + +from .. import ( + opentime, + exceptions, +) + +from . import ( + serializable_object, + composable, +) + + +class Item(composable.Composable): + """An Item is a Composable that can be part of a Composition or Timeline. + + More specifically, it is a Composable that has meaningful duration. + + Can also hold effects and markers. + + Base class of: + - Composition (and children) + - Clip + - Gap + """ + + _serializable_label = "Item.1" + _class_path = "core.Item" + + def __init__( + self, + name=None, + source_range=None, + effects=None, + markers=None, + metadata=None, + ): + super(Item, self).__init__(name=name, metadata=metadata) + + self.source_range = copy.deepcopy(source_range) + self.effects = copy.deepcopy(effects) if effects else [] + self.markers = copy.deepcopy(markers) if markers else [] + + name = serializable_object.serializable_field("name", doc="Item name.") + source_range = serializable_object.serializable_field( + "source_range", + opentime.TimeRange, + doc="Range of source to trim to. Can be None or a TimeRange." + ) + + @staticmethod + def visible(): + """Return the visibility of the Item. By default True.""" + + return True + + def duration(self): + """Convience wrapper for the trimmed_range.duration of the item.""" + + return self.trimmed_range().duration + + def available_range(self): + """Implemented by child classes, available range of media.""" + + raise NotImplementedError + + def trimmed_range(self): + """The range after applying the source range.""" + if self.source_range is not None: + return copy.copy(self.source_range) + + return self.available_range() + + def visible_range(self): + """The range of this item's media visible to its parent. + Includes handles revealed by adjacent transitions (if any). + This will always be larger or equal to trimmed_range().""" + result = self.trimmed_range() + if self.parent(): + head, tail = self.parent().handles_of_child(self) + if head: + result = opentime.TimeRange( + start_time=result.start_time - head, + duration=result.duration + head + ) + if tail: + result = opentime.TimeRange( + start_time=result.start_time, + duration=result.duration + tail + ) + return result + + def trimmed_range_in_parent(self): + """Find and return the trimmed range of this item in the parent.""" + if not self.parent(): + raise exceptions.NotAChildError( + "No parent of {}, cannot compute range in parent.".format(self) + ) + + return self.parent().trimmed_range_of_child(self) + + def range_in_parent(self): + """Find and return the untrimmed range of this item in the parent.""" + if not self.parent(): + raise exceptions.NotAChildError( + "No parent of {}, cannot compute range in parent.".format(self) + ) + + return self.parent().range_of_child(self) + + def transformed_time(self, t, to_item): + """Converts time t in the coordinate system of self to coordinate + system of to_item. + + Note that self and to_item must be part of the same timeline (they must + have a common ancestor). + + Example: + + 0 20 + [------t----D----------] + [--A-][t----B---][--C--] + 100 101 110 + 101 in B = 6 in D + + t = t argument + """ + + if not isinstance(t, opentime.RationalTime): + raise ValueError( + "transformed_time only operates on RationalTime, not {}".format( + type(t) + ) + ) + + # does not operate in place + result = copy.copy(t) + + if to_item is None: + return result + + root = self._root_parent() + + # transform t to root parent's coordinate system + item = self + while item != root and item != to_item: + + parent = item.parent() + result -= item.trimmed_range().start_time + result += parent.range_of_child(item).start_time + + item = parent + + ancestor = item + + # transform from root parent's coordinate system to to_item + item = to_item + while item != root and item != ancestor: + + parent = item.parent() + result += item.trimmed_range().start_time + result -= parent.range_of_child(item).start_time + + item = parent + + assert(item is ancestor) + + return result + + def transformed_time_range(self, tr, to_item): + """Transforms the timerange tr to the range of child or self to_item.""" + + return opentime.TimeRange( + self.transformed_time(tr.start_time, to_item), + tr.duration + ) + + markers = serializable_object.serializable_field( + "markers", + doc="List of markers on this item." + ) + effects = serializable_object.serializable_field( + "effects", + doc="List of effects on this item." + ) + metadata = serializable_object.serializable_field( + "metadata", + doc="Metadata dictionary for this item." + ) + + def __repr__(self): + return ( + "otio.{}(" + "name={}, " + "source_range={}, " + "effects={}, " + "markers={}, " + "metadata={}" + ")".format( + self._class_path, + repr(self.name), + repr(self.source_range), + repr(self.effects), + repr(self.markers), + repr(self.metadata) + ) + ) + + def __str__(self): + return "{}({}, {}, {}, {}, {})".format( + self._class_path.split('.')[-1], + self.name, + str(self.source_range), + str(self.effects), + str(self.markers), + str(self.metadata) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/core/json_serializer.py b/pype/vendor/python/python_2/opentimelineio/core/json_serializer.py new file mode 100644 index 0000000000..fee8242143 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/json_serializer.py @@ -0,0 +1,218 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Serializer for SerializableObjects to JSON + +Used for the otio_json adapter as well as for plugins and manifests. +""" + +import json + +from . import ( + SerializableObject, + type_registry, +) + +from .unknown_schema import UnknownSchema + +from .. import ( + exceptions, + opentime, +) + + +# @TODO: Handle file version drifting + + +class _SerializableObjectEncoder(json.JSONEncoder): + + """ Encoder for the SerializableObject OTIO Class and its descendents. """ + + def default(self, obj): + for typename, encfn in _ENCODER_LIST: + if isinstance(obj, typename): + return encfn(obj) + + return json.JSONEncoder.default(self, obj) + + +def serialize_json_to_string(root, indent=4): + """Serialize a tree of SerializableObject to JSON. + + Returns a JSON string. + """ + + return _SerializableObjectEncoder( + sort_keys=True, + indent=indent + ).encode(root) + + +def serialize_json_to_file(root, to_file): + """ + Serialize a tree of SerializableObject to JSON. + + Writes the result to the given file path. + """ + + content = serialize_json_to_string(root) + + with open(to_file, 'w') as file_contents: + file_contents.write(content) + +# @{ Encoders + + +def _encoded_serializable_object(input_otio): + if not input_otio._serializable_label: + raise exceptions.InvalidSerializableLabelError( + input_otio._serializable_label + ) + result = { + "OTIO_SCHEMA": input_otio._serializable_label, + } + result.update(input_otio._data) + return result + + +def _encoded_unknown_schema_object(input_otio): + orig_label = input_otio.data.get(UnknownSchema._original_label) + if not orig_label: + raise exceptions.InvalidSerializableLabelError( + orig_label + ) + # result is just a dict, not a SerializableObject + result = {} + result.update(input_otio.data) + result["OTIO_SCHEMA"] = orig_label # override the UnknownSchema label + del result[UnknownSchema._original_label] + return result + + +def _encoded_time(input_otio): + return { + "OTIO_SCHEMA": "RationalTime.1", + 'value': input_otio.value, + 'rate': input_otio.rate + } + + +def _encoded_time_range(input_otio): + return { + "OTIO_SCHEMA": "TimeRange.1", + 'start_time': _encoded_time(input_otio.start_time), + 'duration': _encoded_time(input_otio.duration) + } + + +def _encoded_transform(input_otio): + return { + "OTIO_SCHEMA": "TimeTransform.1", + 'offset': _encoded_time(input_otio.offset), + 'scale': input_otio.scale, + 'rate': input_otio.rate + } +# @} + + +# Ordered list of functions for encoding OTIO objects to JSON. +# More particular cases should precede more general cases. +_ENCODER_LIST = [ + (opentime.RationalTime, _encoded_time), + (opentime.TimeRange, _encoded_time_range), + (opentime.TimeTransform, _encoded_transform), + (UnknownSchema, _encoded_unknown_schema_object), + (SerializableObject, _encoded_serializable_object) +] + +# @{ Decoders + + +def _decoded_time(input_otio): + return opentime.RationalTime( + input_otio['value'], + input_otio['rate'] + ) + + +def _decoded_time_range(input_otio): + return opentime.TimeRange( + input_otio['start_time'], + input_otio['duration'] + ) + + +def _decoded_transform(input_otio): + return opentime.TimeTransform( + input_otio['offset'], + input_otio['scale'] + ) +# @} + + +# Map of explicit decoder functions to schema labels (for opentime) +# because opentime is implemented with no knowledge of OTIO, it doesn't use the +# same pattern as SerializableObject. +_DECODER_FUNCTION_MAP = { + 'RationalTime.1': _decoded_time, + 'TimeRange.1': _decoded_time_range, + 'TimeTransform.1': _decoded_transform, +} + + +def _as_otio(dct): + """ Specialized JSON decoder for OTIO base Objects. """ + + if "OTIO_SCHEMA" in dct: + schema_label = dct["OTIO_SCHEMA"] + + if schema_label in _DECODER_FUNCTION_MAP: + return _DECODER_FUNCTION_MAP[schema_label](dct) + + schema_name = type_registry.schema_name_from_label(schema_label) + schema_version = type_registry.schema_version_from_label(schema_label) + del dct["OTIO_SCHEMA"] + + return type_registry.instance_from_schema( + schema_name, + schema_version, + dct + ) + + return dct + + +def deserialize_json_from_string(otio_string): + """ Deserialize a string containing JSON to OTIO objects. """ + + return json.loads(otio_string, object_hook=_as_otio) + + +def deserialize_json_from_file(otio_filepath): + """ Deserialize the file at otio_filepath containing JSON to OTIO. """ + + with open(otio_filepath, 'r') as file_contents: + result = deserialize_json_from_string(file_contents.read()) + result._json_path = otio_filepath + return result diff --git a/pype/vendor/python/python_2/opentimelineio/core/media_reference.py b/pype/vendor/python/python_2/opentimelineio/core/media_reference.py new file mode 100644 index 0000000000..ac34852613 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/media_reference.py @@ -0,0 +1,102 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Media Reference Classes and Functions.""" + +from .. import ( + opentime, +) +from . import ( + type_registry, + serializable_object, +) + +import copy + + +@type_registry.register_type +class MediaReference(serializable_object.SerializableObject): + """Base Media Reference Class. + + Currently handles string printing the child classes, which expose interface + into its data dictionary. + + The requirement is that the schema is named so that external systems can + fetch the required information correctly. + """ + _serializable_label = "MediaReference.1" + _name = "MediaReference" + + def __init__( + self, + name=None, + available_range=None, + metadata=None + ): + super(MediaReference, self).__init__() + + self.name = name + self.available_range = copy.deepcopy(available_range) + self.metadata = copy.deepcopy(metadata) or {} + + name = serializable_object.serializable_field( + "name", + doc="Name of this media reference." + ) + available_range = serializable_object.serializable_field( + "available_range", + opentime.TimeRange, + doc="Available range of media in this media reference." + ) + metadata = serializable_object.serializable_field( + "metadata", + dict, + doc="Metadata dictionary." + ) + + @property + def is_missing_reference(self): + return False + + def __str__(self): + return "{}({}, {}, {})".format( + self._name, + repr(self.name), + repr(self.available_range), + repr(self.metadata) + ) + + def __repr__(self): + return ( + "otio.schema.{}(" + "name={}," + " available_range={}," + " metadata={}" + ")" + ).format( + self._name, + repr(self.name), + repr(self.available_range), + repr(self.metadata) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/core/serializable_object.py b/pype/vendor/python/python_2/opentimelineio/core/serializable_object.py new file mode 100644 index 0000000000..27032569b0 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/serializable_object.py @@ -0,0 +1,219 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implements the otio.core.SerializableObject""" + +import copy + +from . import ( + type_registry, +) + + +class SerializableObject(object): + """Base object for things that can be [de]serialized to/from .otio files. + + To define a new child class of this, you inherit from it and also use the + register_type decorator. Then you use the serializable_field function + above to create attributes that can be serialized/deserialized. + + You can use the upgrade_function_for decorator to upgrade older schemas + to newer ones. + + Finally, if you're in the process of upgrading schemas and you want to + catch code that refers to old attribute names, you can use the + deprecated_field function. This raises an exception if code attempts to + read or write to that attribute. After testing and before pushing, please + remove references to deprecated_field. + + For example + + >>> import opentimelineio as otio + + >>> @otio.core.register_type + ... class ExampleChild(otio.core.SerializableObject): + ... _serializable_label = "ExampleChild.7" + ... child_data = otio.core.serializable_field("child_data", int) + + # @TODO: delete once testing shows nothing is referencing this. + >>> old_child_data_name = otio.core.deprecated_field() + + >>> @otio.core.upgrade_function_for(ExampleChild, 3) + ... def upgrade_child_to_three(_data): + ... return {"child_data" : _data["old_child_data_name"]} + """ + + # Every child must define a _serializable_label attribute. + # This attribute is a string in the form of: "SchemaName.VersionNumber" + # Where VersionNumber is an integer. + # You can use the classmethods .schema_name() and .schema_version() to + # query these fields. + _serializable_label = None + _class_path = "core.SerializableObject" + + def __init__(self): + self._data = {} + + # @{ "Reference Type" semantics for SerializableObject + # We think of the SerializableObject as a reference type - by default + # comparison is pointer comparison, but you can use 'is_equivalent_to' to + # check if the contents of the SerializableObject are the same as some + # other SerializableObject's contents. + # + # Implicitly: + # def __eq__(self, other): + # return self is other + + def is_equivalent_to(self, other): + """Returns true if the contents of self and other match.""" + + try: + if self._data == other._data: + return True + + # XXX: Gross hack takes OTIO->JSON String->Python Dictionaries + # + # using the serializer ensures that we only compare fields that are + # serializable, which is how we define equivalence. + # + # we use json.loads() to turn the string back into dictionaries + # so we can use python's equivalence for things like floating + # point numbers (ie 5.0 == 5) without having to do string + # processing. + + from . import json_serializer + import json + + lhs_str = json_serializer.serialize_json_to_string(self) + lhs = json.loads(lhs_str) + + rhs_str = json_serializer.serialize_json_to_string(other) + rhs = json.loads(rhs_str) + + return (lhs == rhs) + except AttributeError: + return False + # @} + + def _update(self, d): + """Like the dictionary .update() method. + + Update the _data dictionary of this SerializableObject with the ._data + of d if d is a SerializableObject or if d is a dictionary, d itself. + """ + + if isinstance(d, SerializableObject): + self._data.update(d._data) + else: + self._data.update(d) + + @classmethod + def schema_name(cls): + return type_registry.schema_name_from_label( + cls._serializable_label + ) + + @classmethod + def schema_version(cls): + return type_registry.schema_version_from_label( + cls._serializable_label + ) + + @property + def is_unknown_schema(self): + # in general, SerializableObject will have a known schema + # but UnknownSchema subclass will redefine this property to be True + return False + + def __copy__(self): + raise NotImplementedError( + "Shallow copying is not permitted. Use a deep copy." + ) + + def __deepcopy__(self, md): + result = type(self)() + result._data = copy.deepcopy(self._data, md) + + return result + + def deepcopy(self): + return self.__deepcopy__({}) + + +def serializable_field(name, required_type=None, doc=None): + """Create a serializable_field for child classes of SerializableObject. + + Convienence function for adding attributes to child classes of + SerializableObject in such a way that they will be serialized/deserialized + automatically. + + Use it like this: + class foo(SerializableObject): + bar = serializable_field("bar", required_type=int, doc="example") + + This would indicate that class "foo" has a serializable field "bar". So: + f = foo() + f.bar = "stuff" + + # serialize & deserialize + otio_json = otio.adapters.from_name("otio") + f2 = otio_json.read_from_string(otio_json.write_to_string(f)) + + # fields should be equal + f.bar == f2.bar + + Additionally, the "doc" field will become the documentation for the + property. + """ + + def getter(self): + return self._data[name] + + def setter(self, val): + # always allow None values regardless of value of required_type + if required_type is not None and val is not None: + if not isinstance(val, required_type): + raise TypeError( + "attribute '{}' must be an instance of '{}', not: {}".format( + name, + required_type, + type(val) + ) + ) + + self._data[name] = val + + return property(getter, setter, doc=doc) + + +def deprecated_field(): + """ For marking attributes on a SerializableObject deprecated. """ + + def getter(self): + raise DeprecationWarning + + def setter(self, val): + raise DeprecationWarning + + return property(getter, setter, doc="Deprecated field, do not use.") diff --git a/pype/vendor/python/python_2/opentimelineio/core/type_registry.py b/pype/vendor/python/python_2/opentimelineio/core/type_registry.py new file mode 100644 index 0000000000..de4824c42d --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/type_registry.py @@ -0,0 +1,152 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Core type registry system for registering OTIO types for serialization.""" + +from .. import ( + exceptions +) + + +# Types decorate use register_type() to insert themselves into this map +_OTIO_TYPES = {} + +# maps types to a map of versions to upgrade functions +_UPGRADE_FUNCTIONS = {} + + +def schema_name_from_label(label): + """Return the schema name from the label name.""" + + return label.split(".")[0] + + +def schema_version_from_label(label): + """Return the schema version from the label name.""" + + return int(label.split(".")[1]) + + +def schema_label_from_name_version(schema_name, schema_version): + """Return the serializeable object schema label given the name and version.""" + + return "{}.{}".format(schema_name, schema_version) + + +def register_type(classobj, schemaname=None): + """ Register a class to a Schema Label. + + Normally this is used as a decorator. However, in special cases where a + type has been renamed, you might need to register the new type to multiple + schema names. To do this: + + >>> @core.register_type + ... class MyNewClass(...): + ... pass + + >>> core.register_type(MyNewClass, "MyOldName") + + This will parse the old schema name into the new class type. You may also + need to write an upgrade function if the schema itself has changed. + """ + + if schemaname is None: + schemaname = schema_name_from_label(classobj._serializable_label) + + _OTIO_TYPES[schemaname] = classobj + + return classobj + + +def upgrade_function_for(cls, version_to_upgrade_to): + """Decorator for identifying schema class upgrade functions. + + Example + >>> @upgrade_function_for(MyClass, 5) + ... def upgrade_to_version_five(data): + ... pass + + This will get called to upgrade a schema of MyClass to version 5. My class + must be a class deriving from otio.core.SerializableObject. + + The upgrade function should take a single argument - the dictionary to + upgrade, and return a dictionary with the fields upgraded. + + Remember that you don't need to provide an upgrade function for upgrades + that add or remove fields, only for schema versions that change the field + names. + """ + + def decorator_func(func): + """ Decorator for marking upgrade functions """ + + _UPGRADE_FUNCTIONS.setdefault(cls, {})[version_to_upgrade_to] = func + + return func + + return decorator_func + + +def instance_from_schema(schema_name, schema_version, data_dict): + """Return an instance, of the schema from data in the data_dict.""" + + if schema_name not in _OTIO_TYPES: + from .unknown_schema import UnknownSchema + + # create an object of UnknownSchema type to represent the data + schema_label = schema_label_from_name_version(schema_name, schema_version) + data_dict[UnknownSchema._original_label] = schema_label + unknown_label = UnknownSchema._serializable_label + schema_name = schema_name_from_label(unknown_label) + schema_version = schema_version_from_label(unknown_label) + + cls = _OTIO_TYPES[schema_name] + + schema_version = int(schema_version) + if cls.schema_version() < schema_version: + raise exceptions.UnsupportedSchemaError( + "Schema '{}' has highest version available '{}', which is lower " + "than requested schema version '{}'".format( + schema_name, + cls.schema_version(), + schema_version + ) + ) + + if cls.schema_version() != schema_version: + # since the keys are the versions to upgrade to, sorting the keys + # before iterating through them should ensure that upgrade functions + # are called in order. + for version, upgrade_func in sorted( + _UPGRADE_FUNCTIONS[cls].items() + ): + if version < schema_version: + continue + + data_dict = upgrade_func(data_dict) + + obj = cls() + obj._update(data_dict) + + return obj diff --git a/pype/vendor/python/python_2/opentimelineio/core/unknown_schema.py b/pype/vendor/python/python_2/opentimelineio/core/unknown_schema.py new file mode 100644 index 0000000000..94c187710e --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/core/unknown_schema.py @@ -0,0 +1,50 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +""" +Implementation of the UnknownSchema schema. +""" + +from .serializable_object import SerializableObject +from .type_registry import register_type + + +@register_type +class UnknownSchema(SerializableObject): + """Represents an object whose schema is unknown to us.""" + + _serializable_label = "UnknownSchema.1" + _name = "UnknownSchema" + _original_label = "UnknownSchemaOriginalLabel" + + @property + def is_unknown_schema(self): + return True + + @property + def data(self): + """Exposes the data dictionary of the underlying SerializableObject + directly. + """ + return self._data diff --git a/pype/vendor/python/python_2/opentimelineio/exceptions.py b/pype/vendor/python/python_2/opentimelineio/exceptions.py new file mode 100644 index 0000000000..7726f2ef71 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/exceptions.py @@ -0,0 +1,89 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Exception classes for OpenTimelineIO""" + + +class OTIOError(Exception): + pass + + +class CouldNotReadFileError(OTIOError): + pass + + +class NoKnownAdapterForExtensionError(OTIOError): + pass + + +class ReadingNotSupportedError(OTIOError): + pass + + +class WritingNotSupportedError(OTIOError): + pass + + +class NotSupportedError(OTIOError): + pass + + +class InvalidSerializableLabelError(OTIOError): + pass + + +class CannotComputeAvailableRangeError(OTIOError): + pass + + +class AdapterDoesntSupportFunctionError(OTIOError): + pass + + +class UnsupportedSchemaError(OTIOError): + pass + + +class NotAChildError(OTIOError): + pass + + +class InstancingNotAllowedError(OTIOError): + pass + + +class TransitionFollowingATransitionError(OTIOError): + pass + + +class MisconfiguredPluginError(OTIOError): + pass + + +class CannotTrimTransitionsError(OTIOError): + pass + + +class NoDefaultMediaLinkerError(OTIOError): + pass diff --git a/pype/vendor/python/python_2/opentimelineio/hooks.py b/pype/vendor/python/python_2/opentimelineio/hooks.py new file mode 100644 index 0000000000..311154553d --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/hooks.py @@ -0,0 +1,174 @@ +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +from . import ( + plugins, + core, +) + +__doc__ = """ +HookScripts are plugins that run at defined points ("Hooks"). + +They expose a hook_function with signature: +hook_function :: otio.schema.Timeline, Dict -> otio.schema.Timeline + +Both hook scripts and the hooks they attach to are defined in the plugin +manifest. + +You can attach multiple hook scripts to a hook. They will be executed in list +order, first to last. + +They are defined by the manifests HookScripts and hooks areas. + +>>> +{ + "OTIO_SCHEMA" : "PluginManifest.1", + "hook_scripts" : [ + { + "OTIO_SCHEMA" : "HookScript.1", + "name" : "example hook", + "execution_scope" : "in process", + "filepath" : "example.py" + } + ], + "hooks" : { + "pre_adapter_write" : ["example hook"], + "post_adapter_read" : [] + } +} + +The 'hook_scripts' area loads the python modules with the 'hook_function's to +call in them. The 'hooks' area defines the hooks (and any associated +scripts). You can further query and modify these from python. + +>>> import opentimelineio as otio +... hook_list = otio.hooks.scripts_attached_to("some_hook") # -> ['a','b','c'] +... +... # to run the hook scripts: +... otio.hooks.run("some_hook", some_timeline, optional_argument_dict) + +This will pass (some_timeline, optional_argument_dict) to 'a', which will +a new timeline that will get passed into 'b' with optional_argument_dict, +etc. + +To Edit the order, change the order in the list: + +>>> hook_list[0], hook_list[2] = hook_list[2], hook_list[0] +... print hook_list # ['c','b','a'] + +Now c will run, then b, then a. + +To delete a function the list: + +>>> del hook_list[1] +""" + + +@core.register_type +class HookScript(plugins.PythonPlugin): + _serializable_label = "HookScript.1" + + def __init__( + self, + name=None, + execution_scope=None, + filepath=None, + ): + """HookScript plugin constructor.""" + + super(HookScript, self).__init__(name, execution_scope, filepath) + + def run(self, in_timeline, argument_map={}): + """Run the hook_function associated with this plugin.""" + + # @TODO: should in_timeline be passed in place? or should a copy be + # made? + return self._execute_function( + "hook_function", + in_timeline=in_timeline, + argument_map=argument_map + ) + + def __str__(self): + return "HookScript({}, {}, {})".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath) + ) + + def __repr__(self): + return ( + "otio.hooks.HookScript(" + "name={}, " + "execution_scope={}, " + "filepath={}" + ")".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath) + ) + ) + + +def names(): + """Return a list of all the registered hooks.""" + + return plugins.ActiveManifest().hooks.keys() + + +def available_hookscript_names(): + """Return the names of HookScripts that have been registered.""" + + return [hs.name for hs in plugins.ActiveManifest().hook_scripts] + + +def available_hookscripts(): + """Return the HookScripts objects that have been registered.""" + return plugins.ActiveManifest().hook_scripts + + +def scripts_attached_to(hook): + """Return an editable list of all the hook scriptss that are attached to + the specified hook, in execution order. Changing this list will change the + order that scripts run in, and deleting a script will remove it from + executing + """ + + # @TODO: Should this return a copy? + return plugins.ActiveManifest().hooks[hook] + + +def run(hook, tl, extra_args=None): + """Run all the scripts associated with hook, passing in tl and extra_args. + + Will return the return value of the last hook script. + + If no hookscripts are defined, returns tl. + """ + + hook_scripts = plugins.ActiveManifest().hooks[hook] + for name in hook_scripts: + hs = plugins.ActiveManifest().from_name(name, "hook_scripts") + tl = hs.run(tl, extra_args) + return tl diff --git a/pype/vendor/python/python_2/opentimelineio/media_linker.py b/pype/vendor/python/python_2/opentimelineio/media_linker.py new file mode 100644 index 0000000000..25473ac1d5 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/media_linker.py @@ -0,0 +1,169 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +""" MediaLinker plugins fire after an adapter has read a file in order to +produce MediaReferences that point at valid, site specific media. + +They expose a "link_media_reference" function with the signature: +link_media_reference :: otio.schema.Clip -> otio.core.MediaReference + +or: + def linked_media_reference(from_clip): + result = otio.core.MediaReference() # whichever subclass + # do stuff + return result + +To get context information, they can inspect the metadata on the clip and on +the media reference. The .parent() method can be used to find the containing +track if metadata is stored there. + +Please raise an instance (or child instance) of +otio.exceptions.CannotLinkMediaError() if there is a problem linking the media. + +For example: + for clip in timeline.each_clip(): + try: + new_mr = otio.media_linker.linked_media_reference(clip) + clip.media_reference = new_mr + except otio.exceptions.CannotLinkMediaError: + # or report the error + pass +""" + +import os + +from . import ( + exceptions, + plugins, + core, +) + + +# Enum describing different media linker policies +class MediaLinkingPolicy: + DoNotLinkMedia = "__do_not_link_media" + ForceDefaultLinker = "__default" + + +# @TODO: wrap this up in the plugin system somehow? automatically generate? +def available_media_linker_names(): + """Return a string list of the available media linker plugins.""" + + return [str(adp.name) for adp in plugins.ActiveManifest().media_linkers] + + +def from_name(name): + """Fetch the media linker object by the name of the adapter directly.""" + + if name == MediaLinkingPolicy.ForceDefaultLinker or not name: + name = os.environ.get("OTIO_DEFAULT_MEDIA_LINKER", None) + + if not name: + return None + + # @TODO: make this handle the enums + try: + return plugins.ActiveManifest().from_name( + name, + kind_list="media_linkers" + ) + except exceptions.NotSupportedError: + raise exceptions.NotSupportedError( + "media linker not supported: {}, available: {}".format( + name, + available_media_linker_names() + ) + ) + + +def default_media_linker(): + try: + return os.environ['OTIO_DEFAULT_MEDIA_LINKER'] + except KeyError: + raise exceptions.NoDefaultMediaLinkerError( + "No default Media Linker set in $OTIO_DEFAULT_MEDIA_LINKER" + ) + + +def linked_media_reference( + target_clip, + media_linker_name=MediaLinkingPolicy.ForceDefaultLinker, + media_linker_argument_map=None +): + media_linker = from_name(media_linker_name) + + if not media_linker: + return target_clip + + # @TODO: connect this argument map up to the function call through to the + # real linker + if not media_linker_argument_map: + media_linker_argument_map = {} + + return media_linker.link_media_reference( + target_clip, + media_linker_argument_map + ) + + +@core.register_type +class MediaLinker(plugins.PythonPlugin): + _serializable_label = "MediaLinker.1" + + def __init__( + self, + name=None, + execution_scope=None, + filepath=None, + ): + super(MediaLinker, self).__init__(name, execution_scope, filepath) + + def link_media_reference(self, in_clip, media_linker_argument_map=None): + media_linker_argument_map = media_linker_argument_map or {} + + return self._execute_function( + "link_media_reference", + in_clip=in_clip, + media_linker_argument_map=media_linker_argument_map + ) + + def __str__(self): + return "MediaLinker({}, {}, {})".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath) + ) + + def __repr__(self): + return ( + "otio.media_linker.MediaLinker(" + "name={}, " + "execution_scope={}, " + "filepath={}" + ")".format( + repr(self.name), + repr(self.execution_scope), + repr(self.filepath) + ) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/opentime.py b/pype/vendor/python/python_2/opentimelineio/opentime.py new file mode 100644 index 0000000000..e7e58b9475 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/opentime.py @@ -0,0 +1,856 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Library for expressing and transforming time. + +NOTE: This module is written specifically with a future port to C in mind. +When ported to C, Time will be a struct and these functions should be very +simple. +""" + +import math +import copy + + +VALID_NON_DROPFRAME_TIMECODE_RATES = ( + 1, + 12, + 23.976, + 23.98, + (24000 / 1001.0), + 24, + 25, + 30, + 29.97, + (30000 / 1001.0), + 48, + 50, + 59.94, + (60000 / 1001.0), + 60, +) + +VALID_DROPFRAME_TIMECODE_RATES = ( + 29.97, + (30000 / 1001.0), + 59.94, + (60000 / 1001.0), +) + +VALID_TIMECODE_RATES = ( + VALID_NON_DROPFRAME_TIMECODE_RATES + VALID_DROPFRAME_TIMECODE_RATES) + +_fn_cache = object.__setattr__ + + +class RationalTime(object): + """ Represents an instantaneous point in time, value * (1/rate) seconds + from time 0seconds. + """ + + # Locks RationalTime instances to only these attributes + __slots__ = ['value', 'rate'] + + def __init__(self, value=0.0, rate=1.0): + _fn_cache(self, "value", value) + _fn_cache(self, "rate", rate) + + def __setattr__(self, key, val): + """Enforces immutability """ + raise AttributeError("RationalTime is Immutable.") + + def __copy__(self, memodict=None): + return RationalTime(self.value, self.rate) + + # Always deepcopy, since we want this class to behave like a value type + __deepcopy__ = __copy__ + + def rescaled_to(self, new_rate): + """Returns the time for this time converted to new_rate""" + + try: + new_rate = new_rate.rate + except AttributeError: + pass + + if self.rate == new_rate: + return copy.copy(self) + + return RationalTime( + self.value_rescaled_to(new_rate), + new_rate + ) + + def value_rescaled_to(self, new_rate): + """Returns the time value for self converted to new_rate""" + + try: + new_rate = new_rate.rate + except AttributeError: + pass + + if new_rate == self.rate: + return self.value + + # TODO: This math probably needs some overrun protection + try: + return float(self.value) * float(new_rate) / float(self.rate) + except (AttributeError, TypeError, ValueError): + raise TypeError( + "Sorry, RationalTime cannot be rescaled to a value of type " + "'{}', only RationalTime and numbers are supported.".format( + type(new_rate) + ) + ) + + def almost_equal(self, other, delta=0.0): + try: + rescaled_value = self.value_rescaled_to(other.rate) + return abs(rescaled_value - other.value) <= delta + + except AttributeError: + return False + + def __add__(self, other): + """Returns a RationalTime object that is the sum of self and other. + + If self and other have differing time rates, the result will have the + have the rate of the faster time. + """ + + try: + if self.rate == other.rate: + return RationalTime(self.value + other.value, self.rate) + except AttributeError: + if not isinstance(other, RationalTime): + raise TypeError( + "RationalTime may only be added to other objects of type " + "RationalTime, not {}.".format(type(other)) + ) + raise + + if self.rate > other.rate: + scale = self.rate + value = self.value + other.value_rescaled_to(scale) + else: + scale = other.rate + value = self.value_rescaled_to(scale) + other.value + + return RationalTime(value, scale) + + # because RationalTime is immutable, += is sugar around + + __iadd__ = __add__ + + def __sub__(self, other): + """Returns a RationalTime object that is self - other. + + If self and other have differing time rates, the result will have the + have the rate of the faster time. + """ + + try: + if self.rate == other.rate: + return RationalTime(self.value - other.value, self.rate) + except AttributeError: + if not isinstance(other, RationalTime): + raise TypeError( + "RationalTime may only be added to other objects of type " + "RationalTime, not {}.".format(type(other)) + ) + raise + + if self.rate > other.rate: + scale = self.rate + value = self.value - other.value_rescaled_to(scale) + else: + scale = other.rate + value = self.value_rescaled_to(scale) - other.value + + return RationalTime(value=value, rate=scale) + + def _comparable_floats(self, other): + """Returns a tuple of two floats, (self, other), which are suitable + for comparison. + + If other is not of a type that can be compared, TypeError is raised + """ + try: + return ( + float(self.value) / self.rate, + float(other.value) / other.rate + ) + except AttributeError: + if not isinstance(other, RationalTime): + raise TypeError( + "RationalTime can only be compared to other objects of type " + "RationalTime, not {}".format(type(other)) + ) + raise + + def __gt__(self, other): + f_self, f_other = self._comparable_floats(other) + return f_self > f_other + + def __lt__(self, other): + f_self, f_other = self._comparable_floats(other) + return f_self < f_other + + def __le__(self, other): + f_self, f_other = self._comparable_floats(other) + return f_self <= f_other + + def __ge__(self, other): + f_self, f_other = self._comparable_floats(other) + return f_self >= f_other + + def __repr__(self): + return ( + "otio.opentime.RationalTime(value={value}," + " rate={rate})".format( + value=repr(self.value), + rate=repr(self.rate), + ) + ) + + def __str__(self): + return "RationalTime({}, {})".format( + str(self.value), + str(self.rate) + ) + + def __eq__(self, other): + try: + return self.value_rescaled_to(other.rate) == other.value + except AttributeError: + return False + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.value, self.rate)) + + +class TimeTransform(object): + """1D Transform for RationalTime. Has offset and scale.""" + + def __init__(self, offset=RationalTime(), scale=1.0, rate=None): + self.offset = copy.copy(offset) + self.scale = float(scale) + self.rate = float(rate) if rate else None + + def applied_to(self, other): + if isinstance(other, TimeRange): + return range_from_start_end_time( + start_time=self.applied_to(other.start_time), + end_time_exclusive=self.applied_to(other.end_time_exclusive()) + ) + + target_rate = self.rate if self.rate is not None else other.rate + if isinstance(other, TimeTransform): + return TimeTransform( + offset=self.offset + other.offset, + scale=self.scale * other.scale, + rate=target_rate + ) + elif isinstance(other, RationalTime): + value = other.value * self.scale + result = RationalTime(value, other.rate) + self.offset + if target_rate is not None: + result = result.rescaled_to(target_rate) + + return result + else: + raise TypeError( + "TimeTransform can only be applied to a TimeTransform or " + "RationalTime, not a {}".format(type(other)) + ) + + def __repr__(self): + return ( + "otio.opentime.TimeTransform(offset={}, scale={}, rate={})".format( + repr(self.offset), + repr(self.scale), + repr(self.rate) + ) + ) + + def __str__(self): + return ( + "TimeTransform({}, {}, {})".format( + str(self.offset), + str(self.scale), + str(self.rate) + ) + ) + + def __eq__(self, other): + try: + return ( + (self.offset, self.scale, self.rate) == + (other.offset, other.scale, self.rate) + ) + except AttributeError: + return False + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.offset, self.scale, self.rate)) + + +class BoundStrategy(object): + """Different bounding strategies for TimeRange """ + + Free = 1 + Clamp = 2 + + +class TimeRange(object): + """Contains a range of time, starting (and including) start_time and + lasting duration.value * (1/duration.rate) seconds. + + A 0 duration TimeRange is the same as a RationalTime, and contains only the + start_time of the TimeRange. + """ + + __slots__ = ['start_time', 'duration'] + + def __init__(self, start_time=None, duration=None): + if not isinstance(start_time, RationalTime) and start_time is not None: + raise TypeError( + "start_time must be a RationalTime, not " + "'{}'".format(start_time) + ) + if ( + duration is not None and ( + not isinstance(duration, RationalTime) + or duration.value < 0.0 + ) + ): + raise TypeError( + "duration must be a RationalTime with value >= 0, not " + "'{}'".format(duration) + ) + + # if the start time has not been passed in + if not start_time: + if duration: + # ...get the rate from the duration + start_time = RationalTime(rate=duration.rate) + else: + # otherwise use the default + start_time = RationalTime() + _fn_cache(self, "start_time", copy.copy(start_time)) + + if not duration: + # ...get the rate from the start_time + duration = RationalTime(rate=start_time.rate) + _fn_cache(self, "duration", copy.copy(duration)) + + def __setattr__(self, key, val): + raise AttributeError("TimeRange is Immutable.") + + def __copy__(self, memodict=None): + # Construct a new one directly to avoid the overhead of deepcopy + return TimeRange( + copy.copy(self.start_time), + copy.copy(self.duration) + ) + + # Always deepcopy, since we want this class to behave like a value type + __deepcopy__ = __copy__ + + def end_time_inclusive(self): + """The time of the last sample that contains data in the TimeRange. + + If the TimeRange goes from (0, 24) w/ duration (10, 24), this will be + (9, 24) + + If the TimeRange goes from (0, 24) w/ duration (10.5, 24): + (10, 24) + + In other words, the last frame with data (however fractional). + """ + + if ( + self.end_time_exclusive() - self.start_time.rescaled_to(self.duration) + ).value > 1: + + result = ( + self.end_time_exclusive() - RationalTime(1, self.start_time.rate) + ) + + # if the duration's value has a fractional component + if self.duration.value != math.floor(self.duration.value): + result = RationalTime( + math.floor(self.end_time_exclusive().value), + result.rate + ) + + return result + else: + return copy.deepcopy(self.start_time) + + def end_time_exclusive(self): + """"Time of the first sample outside the time range. + + If Start Frame is 10 and duration is 5, then end_time_exclusive is 15, + even though the last time with data in this range is 14. + + If Start Frame is 10 and duration is 5.5, then end_time_exclusive is + 15.5, even though the last time with data in this range is 15. + """ + + return self.duration + self.start_time.rescaled_to(self.duration) + + def extended_by(self, other): + """Construct a new TimeRange that is this one extended by another.""" + + if not isinstance(other, TimeRange): + raise TypeError( + "extended_by requires rtime be a TimeRange, not a '{}'".format( + type(other) + ) + ) + + start_time = min(self.start_time, other.start_time) + new_end_time = max( + self.end_time_exclusive(), + other.end_time_exclusive() + ) + duration = duration_from_start_end_time(start_time, new_end_time) + return TimeRange(start_time, duration) + + # @TODO: remove? + def clamped( + self, + other, + start_bound=BoundStrategy.Free, + end_bound=BoundStrategy.Free + ): + """Clamp 'other' (either a RationalTime or a TimeRange), according to + self.start_time/end_time_exclusive and the bound arguments. + """ + + if isinstance(other, RationalTime): + if start_bound == BoundStrategy.Clamp: + other = max(other, self.start_time) + if end_bound == BoundStrategy.Clamp: + # @TODO: this should probably be the end_time_inclusive, + # not exclusive + other = min(other, self.end_time_exclusive()) + return other + elif isinstance(other, TimeRange): + start_time = other.start_time + end = other.end_time_exclusive() + if start_bound == BoundStrategy.Clamp: + start_time = max(other.start_time, self.start_time) + if end_bound == BoundStrategy.Clamp: + end = min(self.end_time_exclusive(), end) + duration = duration_from_start_end_time(start_time, end) + return TimeRange(start_time, duration) + else: + raise TypeError( + "TimeRange can only be applied to RationalTime objects, not " + "{}".format(type(other)) + ) + return self + + def contains(self, other): + """Return true if self completely contains other. + + (RationalTime or TimeRange) + """ + + if isinstance(other, RationalTime): + return ( + self.start_time <= other and other < self.end_time_exclusive()) + elif isinstance(other, TimeRange): + return ( + self.start_time <= other.start_time and + self.end_time_exclusive() >= other.end_time_exclusive() + ) + raise TypeError( + "contains only accepts on otio.opentime.RationalTime or " + "otio.opentime.TimeRange, not {}".format(type(other)) + ) + + def overlaps(self, other): + """Return true if self overlaps any part of other. + + (RationalTime or TimeRange) + """ + + if isinstance(other, RationalTime): + return self.contains(other) + elif isinstance(other, TimeRange): + return ( + ( + self.start_time < other.end_time_exclusive() and + other.start_time < self.end_time_exclusive() + ) + ) + raise TypeError( + "overlaps only accepts on otio.opentime.RationalTime or " + "otio.opentime.TimeRange, not {}".format(type(other)) + ) + + def __hash__(self): + return hash((self.start_time, self.duration)) + + def __eq__(self, rhs): + try: + return ( + (self.start_time, self.duration) == + (rhs.start_time, rhs.duration) + ) + except AttributeError: + return False + + def __ne__(self, rhs): + return not (self == rhs) + + def __repr__(self): + return ( + "otio.opentime.TimeRange(start_time={}, duration={})".format( + repr(self.start_time), + repr(self.duration), + ) + ) + + def __str__(self): + return ( + "TimeRange({}, {})".format( + str(self.start_time), + str(self.duration), + ) + ) + + +def from_frames(frame, fps): + """Turn a frame number and fps into a time object. + :param frame: (:class:`int`) Frame number. + :param fps: (:class:`float`) Frame-rate for the (:class:`RationalTime`) instance. + + :return: (:class:`RationalTime`) Instance for the frame and fps provided. + """ + + return RationalTime(int(frame), fps) + + +def to_frames(time_obj, fps=None): + """Turn a RationalTime into a frame number.""" + + if not fps or time_obj.rate == fps: + return int(time_obj.value) + + return int(time_obj.value_rescaled_to(fps)) + + +def validate_timecode_rate(rate): + """Check if rate is of valid type and value. + Raises (:class:`TypeError` for wrong type of rate. + Raises (:class:`VaueError`) for invalid rate value. + + :param rate: (:class:`int`) or (:class:`float`) The frame rate in question + """ + if not isinstance(rate, (int, float)): + raise TypeError( + "rate must be or not {t}".format(t=type(rate))) + + if rate not in VALID_TIMECODE_RATES: + raise ValueError( + '{rate} is not a valid frame rate, ' + 'Please use one of these: {valid}'.format( + rate=rate, + valid=VALID_TIMECODE_RATES)) + + +def from_timecode(timecode_str, rate): + """Convert a timecode string into a RationalTime. + + :param timecode_str: (:class:`str`) A colon-delimited timecode. + :param rate: (:class:`float`) The frame-rate to calculate timecode in + terms of. + + :return: (:class:`RationalTime`) Instance for the timecode provided. + """ + # Validate rate + validate_timecode_rate(rate) + + # Check if rate is drop frame + rate_is_dropframe = rate in VALID_DROPFRAME_TIMECODE_RATES + + # Make sure only DF timecodes are treated as such + treat_as_df = rate_is_dropframe and ';' in timecode_str + + # Check if timecode indicates drop frame + if ';' in timecode_str: + if not rate_is_dropframe: + raise ValueError( + 'Timecode "{}" indicates drop-frame rate ' + 'due to the ";" frame divider. ' + 'Passed rate ({}) is of non-drop-frame rate. ' + 'Valid drop-frame rates are: {}'.format( + timecode_str, + rate, + VALID_DROPFRAME_TIMECODE_RATES)) + else: + timecode_str = timecode_str.replace(';', ':') + + hours, minutes, seconds, frames = timecode_str.split(":") + + # Timecode is declared in terms of nominal fps + nominal_fps = int(math.ceil(rate)) + + if int(frames) >= nominal_fps: + raise ValueError( + 'Frame rate mismatch. Timecode "{}" has frames beyond {}.'.format( + timecode_str, nominal_fps - 1)) + + dropframes = 0 + if treat_as_df: + if rate == 29.97: + dropframes = 2 + + elif rate == 59.94: + dropframes = 4 + + # To use for drop frame compensation + total_minutes = int(hours) * 60 + int(minutes) + + # convert to frames + value = ( + ((total_minutes * 60) + int(seconds)) * nominal_fps + int(frames)) - \ + (dropframes * (total_minutes - (total_minutes // 10))) + + return RationalTime(value, rate) + + +def to_timecode(time_obj, rate=None, drop_frame=None): + """Convert a RationalTime into a timecode string. + + :param time_obj: (:class:`RationalTime`) instance to express as timecode. + :param rate: (:class:`float`) The frame-rate to calculate timecode in + terms of. (Default time_obj.rate) + :param drop_frame: (:class:`bool`) ``True`` to make drop-frame timecode, + ``False`` for non-drop. If left ``None``, a format will be guessed + based on rate. + + :return: (:class:`str`) The timecode. + """ + if time_obj is None: + return None + + rate = rate or time_obj.rate + + # Validate rate + validate_timecode_rate(rate) + + # Check if rate is drop frame + rate_is_dropframe = rate in VALID_DROPFRAME_TIMECODE_RATES + if drop_frame and not rate_is_dropframe: + raise ValueError( + "Invalid rate for drop-frame timecode {}".format(time_obj.rate) + ) + + # if in auto-detect for DFTC, use the rate to decide + if drop_frame is None: + drop_frame = rate_is_dropframe + + dropframes = 0 + if drop_frame: + if rate in (29.97, (30000 / 1001.0)): + dropframes = 2 + + elif rate == 59.94: + dropframes = 4 + + # For non-dftc, use the integral frame rate + if not drop_frame: + rate = round(rate) + + # Number of frames in an hour + frames_per_hour = int(round(rate * 60 * 60)) + # Number of frames in a day - timecode rolls over after 24 hours + frames_per_24_hours = frames_per_hour * 24 + # Number of frames per ten minutes + frames_per_10_minutes = int(round(rate * 60 * 10)) + # Number of frames per minute is the round of the framerate * 60 minus + # the number of dropped frames + frames_per_minute = int(round(rate) * 60) - dropframes + + value = time_obj.value + + if value < 0: + raise ValueError( + "Negative values are not supported for converting to timecode.") + + # If frame_number is greater than 24 hrs, next operation will rollover + # clock + value %= frames_per_24_hours + + if drop_frame: + d = value // frames_per_10_minutes + m = value % frames_per_10_minutes + if m > dropframes: + value += (dropframes * 9 * d) + \ + dropframes * ((m - dropframes) // frames_per_minute) + else: + value += dropframes * 9 * d + + nominal_fps = int(math.ceil(rate)) + + frames = value % nominal_fps + seconds = (value // nominal_fps) % 60 + minutes = ((value // nominal_fps) // 60) % 60 + hours = (((value // nominal_fps) // 60) // 60) + + tc = "{HH:02d}:{MM:02d}:{SS:02d}{div}{FF:02d}" + + return tc.format( + HH=int(hours), + MM=int(minutes), + SS=int(seconds), + div=drop_frame and ";" or ":", + FF=int(frames)) + + +def from_time_string(time_str, rate): + """Convert a time with microseconds string into a RationalTime. + + :param time_str: (:class:`str`) A HH:MM:ss.ms time. + :param rate: (:class:`float`) The frame-rate to calculate timecode in + terms of. + + :return: (:class:`RationalTime`) Instance for the timecode provided. + """ + + if ';' in time_str: + raise ValueError('Drop-Frame timecodes not supported.') + + hours, minutes, seconds = time_str.split(":") + microseconds = "0" + if '.' in seconds: + seconds, microseconds = str(seconds).split('.') + microseconds = microseconds[0:6] + seconds = '.'.join([seconds, microseconds]) + time_obj = from_seconds( + float(seconds) + + (int(minutes) * 60) + + (int(hours) * 60 * 60) + ) + return time_obj.rescaled_to(rate) + + +def to_time_string(time_obj): + """ + Convert this timecode to time with microsecond, as formated in FFMPEG + + :return: Number formated string of time + """ + if time_obj is None: + return None + # convert time object to seconds + seconds = to_seconds(time_obj) + + # reformat in time string + time_units_per_minute = 60 + time_units_per_hour = time_units_per_minute * 60 + time_units_per_day = time_units_per_hour * 24 + + days, hour_units = divmod(seconds, time_units_per_day) + hours, minute_units = divmod(hour_units, time_units_per_hour) + minutes, seconds = divmod(minute_units, time_units_per_minute) + microseconds = "0" + seconds = str(seconds) + if '.' in seconds: + seconds, microseconds = str(seconds).split('.') + + # TODO: There are some rollover policy issues for days and hours, + # We need to research these + + return "{hours}:{minutes}:{seconds}.{microseconds}".format( + hours="{n:0{width}d}".format(n=int(hours), width=2), + minutes="{n:0{width}d}".format(n=int(minutes), width=2), + seconds="{n:0{width}d}".format(n=int(seconds), width=2), + microseconds=microseconds[0:6] + ) + + +def from_seconds(seconds): + """Convert a number of seconds into RationalTime""" + + # Note: in the future we may consider adding a preferred rate arg + time_obj = RationalTime(value=seconds, rate=1) + + return time_obj + + +def to_seconds(time_obj): + """ Convert a RationalTime into float seconds """ + return time_obj.value_rescaled_to(1) + + +def from_footage(footage): + raise NotImplementedError + + +def to_footage(time_obj): + raise NotImplementedError + + +def duration_from_start_end_time(start_time, end_time_exclusive): + """Compute duration of samples from first to last. This is not the same as + distance. For example, the duration of a clip from frame 10 to frame 15 + is 6 frames. Result in the rate of start_time. + """ + + # @TODO: what to do when start_time > end_time_exclusive? + + if start_time.rate == end_time_exclusive.rate: + return RationalTime( + end_time_exclusive.value - start_time.value, + start_time.rate + ) + else: + return RationalTime( + ( + end_time_exclusive.value_rescaled_to(start_time) + - start_time.value + ), + start_time.rate + ) + + +# @TODO: create range from start/end [in,ex]clusive +def range_from_start_end_time(start_time, end_time_exclusive): + """Create a TimeRange from start and end RationalTimes.""" + + return TimeRange( + start_time, + duration=duration_from_start_end_time(start_time, end_time_exclusive) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/plugins/__init__.py b/pype/vendor/python/python_2/opentimelineio/plugins/__init__.py new file mode 100644 index 0000000000..dedb3da37e --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/plugins/__init__.py @@ -0,0 +1,33 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Plugin system for OTIO""" + +# flake8: noqa + +from .python_plugin import PythonPlugin +from .manifest import ( + manifest_from_file, + ActiveManifest, +) diff --git a/pype/vendor/python/python_2/opentimelineio/plugins/manifest.py b/pype/vendor/python/python_2/opentimelineio/plugins/manifest.py new file mode 100644 index 0000000000..2a769effec --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/plugins/manifest.py @@ -0,0 +1,282 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of an adapter registry system for OTIO.""" + +import inspect +import logging +import os + +# on some python interpreters, pkg_resources is not available +try: + import pkg_resources +except ImportError: + pkg_resources = None + +from .. import ( + core, + exceptions, +) + + +def manifest_from_file(filepath): + """Read the .json file at filepath into a Manifest object.""" + + result = core.deserialize_json_from_file(filepath) + result.source_files.append(filepath) + result._update_plugin_source(filepath) + return result + + +def manifest_from_string(input_string): + """Deserialize the json string into a manifest object.""" + + result = core.deserialize_json_from_string(input_string) + + # try and get the caller's name + name = "unknown" + stack = inspect.stack() + if len(stack) > 1 and len(stack[1]) > 3: + # filename function name + name = "{}:{}".format(stack[1][1], stack[1][3]) + + # set the value in the manifest + src_string = "call to manifest_from_string() in " + name + result.source_files.append(src_string) + result._update_plugin_source(src_string) + + return result + + +@core.register_type +class Manifest(core.SerializableObject): + """Defines an OTIO plugin Manifest. + + This is an internal OTIO implementation detail. A manifest tracks a + collection of adapters and allows finding specific adapters by suffix + + For writing your own adapters, consult: + https://opentimelineio.readthedocs.io/en/latest/tutorials/write-an-adapter.html# + """ + _serializable_label = "PluginManifest.1" + + def __init__(self): + super(Manifest, self).__init__() + self.adapters = [] + self.schemadefs = [] + self.media_linkers = [] + self.source_files = [] + + # hook system stuff + self.hooks = {} + self.hook_scripts = [] + + adapters = core.serializable_field( + "adapters", + type([]), + "Adapters this manifest describes." + ) + schemadefs = core.serializable_field( + "schemadefs", + type([]), + "Schemadefs this manifest describes." + ) + media_linkers = core.serializable_field( + "media_linkers", + type([]), + "Media Linkers this manifest describes." + ) + hooks = core.serializable_field( + "hooks", + type({}), + "Hooks that hooks scripts can be attached to." + ) + hook_scripts = core.serializable_field( + "hook_scripts", + type([]), + "Scripts that can be attached to hooks." + ) + + def extend(self, another_manifest): + """ + Extend the adapters, schemadefs, and media_linkers lists of this manifest + by appending the contents of the corresponding lists of another_manifest. + """ + if another_manifest: + self.adapters.extend(another_manifest.adapters) + self.schemadefs.extend(another_manifest.schemadefs) + self.media_linkers.extend(another_manifest.media_linkers) + self.hook_scripts.extend(another_manifest.hook_scripts) + + for trigger_name, hooks in another_manifest.hooks.items(): + if trigger_name in self.hooks: + self.hooks[trigger_name].extend(hooks) + + def _update_plugin_source(self, path): + """Track the source .json for a given adapter.""" + + for thing in (self.adapters + self.schemadefs + + self.media_linkers + self.hook_scripts): + thing._json_path = path + + def from_filepath(self, suffix): + """Return the adapter object associated with a given file suffix.""" + + for adapter in self.adapters: + if suffix.lower() in adapter.suffixes: + return adapter + raise exceptions.NoKnownAdapterForExtensionError(suffix) + + def adapter_module_from_suffix(self, suffix): + """Return the adapter module associated with a given file suffix.""" + + adp = self.from_filepath(suffix) + return adp.module() + + def from_name(self, name, kind_list="adapters"): + """Return the adapter object associated with a given adapter name.""" + + for thing in getattr(self, kind_list): + if name == thing.name: + return thing + + raise exceptions.NotSupportedError( + "Could not find plugin: '{}' in kind_list: '{}'." + " options: {}".format( + name, + kind_list, + getattr(self, kind_list) + ) + ) + + def adapter_module_from_name(self, name): + """Return the adapter module associated with a given adapter name.""" + + adp = self.from_name(name) + return adp.module() + + def schemadef_module_from_name(self, name): + """Return the schemadef module associated with a given schemadef name.""" + + adp = self.from_name(name, kind_list="schemadefs") + return adp.module() + + +_MANIFEST = None + + +def load_manifest(): + # build the manifest of adapters, starting with builtin adapters + result = manifest_from_file( + os.path.join( + os.path.dirname(os.path.dirname(inspect.getsourcefile(core))), + "adapters", + "builtin_adapters.plugin_manifest.json" + ) + ) + + # layer contrib plugins after built in ones + try: + import opentimelineio_contrib as otio_c + + contrib_manifest = manifest_from_file( + os.path.join( + os.path.dirname(inspect.getsourcefile(otio_c)), + "adapters", + "contrib_adapters.plugin_manifest.json" + ) + ) + result.extend(contrib_manifest) + except ImportError: + pass + + # Discover setuptools-based plugins + if pkg_resources: + for plugin in pkg_resources.iter_entry_points( + "opentimelineio.plugins" + ): + plugin_name = plugin.name + try: + plugin_entry_point = plugin.load() + try: + plugin_manifest = plugin_entry_point.plugin_manifest() + except AttributeError: + if not pkg_resources.resource_exists( + plugin.module_name, + 'plugin_manifest.json' + ): + raise + manifest_stream = pkg_resources.resource_stream( + plugin.module_name, + 'plugin_manifest.json' + ) + plugin_manifest = core.deserialize_json_from_string( + manifest_stream.read().decode('utf-8') + ) + manifest_stream.close() + filepath = pkg_resources.resource_filename( + plugin.module_name, + 'plugin_manifest.json' + ) + plugin_manifest._update_plugin_source(filepath) + + except Exception: + logging.exception( + "could not load plugin: {}".format(plugin_name) + ) + continue + + result.extend(plugin_manifest) + else: + # XXX: Should we print some kind of warning that pkg_resources isn't + # available? + pass + + # read local adapter manifests, if they exist + _local_manifest_path = os.environ.get("OTIO_PLUGIN_MANIFEST_PATH", None) + if _local_manifest_path is not None: + for json_path in _local_manifest_path.split(":"): + if not os.path.exists(json_path): + # XXX: In case error reporting is requested + # print( + # "Warning: OpenTimelineIO cannot access path '{}' from " + # "$OTIO_PLUGIN_MANIFEST_PATH".format(json_path) + # ) + continue + + LOCAL_MANIFEST = manifest_from_file(json_path) + result.extend(LOCAL_MANIFEST) + + # force the schemadefs to load and add to schemadef module namespace + for s in result.schemadefs: + s.module() + return result + + +def ActiveManifest(force_reload=False): + global _MANIFEST + if not _MANIFEST or force_reload: + _MANIFEST = load_manifest() + + return _MANIFEST diff --git a/pype/vendor/python/python_2/opentimelineio/plugins/python_plugin.py b/pype/vendor/python/python_2/opentimelineio/plugins/python_plugin.py new file mode 100644 index 0000000000..c749bd5f9d --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/plugins/python_plugin.py @@ -0,0 +1,128 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Base class for OTIO plugins that are exposed by manifests.""" + +import os +import imp + +from .. import ( + core, + exceptions, +) + + +class PythonPlugin(core.SerializableObject): + """A class of plugin that is encoded in a python module, exposed via a + manifest. + """ + + _serializable_label = "PythonPlugin.1" + + def __init__( + self, + name=None, + execution_scope=None, + filepath=None, + ): + super(PythonPlugin, self).__init__() + self.name = name + self.execution_scope = execution_scope + self.filepath = filepath + self._json_path = None + self._module = None + + name = core.serializable_field("name", doc="Adapter name.") + execution_scope = core.serializable_field( + "execution_scope", + str, + doc=( + "Describes whether this adapter is executed in the current python" + " process or in a subshell. Options are: " + "['in process', 'out of process']." + ) + ) + filepath = core.serializable_field( + "filepath", + str, + doc=( + "Absolute path or relative path to adapter module from location of" + " json." + ) + ) + + def module_abs_path(self): + """Return an absolute path to the module implementing this adapter.""" + + filepath = self.filepath + if not os.path.isabs(filepath): + if not self._json_path: + raise exceptions.MisconfiguredPluginError( + "{} plugin is misconfigured, missing json path. " + "plugin: {}".format( + self.name, + repr(self) + ) + ) + + filepath = os.path.join(os.path.dirname(self._json_path), filepath) + + return filepath + + def _imported_module(self, namespace): + """Load the module this plugin points at.""" + + pyname = os.path.splitext(os.path.basename(self.module_abs_path()))[0] + pydir = os.path.dirname(self.module_abs_path()) + + (file_obj, pathname, description) = imp.find_module(pyname, [pydir]) + + with file_obj: + # this will reload the module if it has already been loaded. + mod = imp.load_module( + "opentimelineio.{}.{}".format(namespace, self.name), + file_obj, + pathname, + description + ) + + return mod + + def module(self): + """Return the module object for this adapter. """ + + if not self._module: + self._module = self._imported_module("adapters") + + return self._module + + def _execute_function(self, func_name, **kwargs): + """Execute func_name on this adapter with error checking.""" + + # collects the error handling into a common place. + if not hasattr(self.module(), func_name): + raise exceptions.AdapterDoesntSupportFunctionError( + "Sorry, {} doesn't support {}.".format(self.name, func_name) + ) + return (getattr(self.module(), func_name)(**kwargs)) diff --git a/pype/vendor/python/python_2/opentimelineio/schema/__init__.py b/pype/vendor/python/python_2/opentimelineio/schema/__init__.py new file mode 100644 index 0000000000..419f337bf6 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/__init__.py @@ -0,0 +1,75 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +# flake8: noqa + +"""User facing classes.""" + +from .missing_reference import ( + MissingReference +) +from .external_reference import ( + ExternalReference +) +from .clip import ( + Clip, +) +from .track import ( + Track, + TrackKind, + NeighborGapPolicy, +) +from .stack import ( + Stack, +) +from .timeline import ( + Timeline, + timeline_from_clips, +) +from .marker import ( + Marker, + MarkerColor, +) +from .gap import ( + Gap, +) +from .effect import ( + Effect, + TimeEffect, + LinearTimeWarp, + FreezeFrame, +) +from .transition import ( + Transition, + TransitionTypes, +) +from .serializable_collection import ( + SerializableCollection +) +from .generator_reference import ( + GeneratorReference +) +from .schemadef import ( + SchemaDef +) diff --git a/pype/vendor/python/python_2/opentimelineio/schema/clip.py b/pype/vendor/python/python_2/opentimelineio/schema/clip.py new file mode 100644 index 0000000000..44d38dfcf1 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/clip.py @@ -0,0 +1,130 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of the Clip class, for pointing at media.""" + +import copy + +from .. import ( + core, + exceptions, +) +from . import ( + missing_reference +) + + +@core.register_type +class Clip(core.Item): + """The base editable object in OTIO. + + Contains a media reference and a trim on that media reference. + """ + + _serializable_label = "Clip.1" + + def __init__( + self, + name=None, + media_reference=None, + source_range=None, + markers=[], + effects=[], + metadata=None, + ): + core.Item.__init__( + self, + name=name, + source_range=source_range, + markers=markers, + effects=effects, + metadata=metadata + ) + + if not media_reference: + media_reference = missing_reference.MissingReference() + self._media_reference = copy.deepcopy(media_reference) + + name = core.serializable_field("name", doc="Name of this clip.") + transform = core.deprecated_field() + _media_reference = core.serializable_field( + "media_reference", + core.MediaReference, + "Media reference to the media this clip represents." + ) + + @property + def media_reference(self): + if self._media_reference is None: + self._media_reference = missing_reference.MissingReference() + return self._media_reference + + @media_reference.setter + def media_reference(self, val): + if val is None: + val = missing_reference.MissingReference() + self._media_reference = val + + def available_range(self): + if not self.media_reference: + raise exceptions.CannotComputeAvailableRangeError( + "No media reference set on clip: {}".format(self) + ) + + if not self.media_reference.available_range: + raise exceptions.CannotComputeAvailableRangeError( + "No available_range set on media reference on clip: {}".format( + self + ) + ) + + return copy.copy(self.media_reference.available_range) + + def __str__(self): + return 'Clip("{}", {}, {}, {})'.format( + self.name, + self.media_reference, + self.source_range, + self.metadata + ) + + def __repr__(self): + return ( + 'otio.schema.Clip(' + 'name={}, ' + 'media_reference={}, ' + 'source_range={}, ' + 'metadata={}' + ')'.format( + repr(self.name), + repr(self.media_reference), + repr(self.source_range), + repr(self.metadata), + ) + ) + + def each_clip(self, search_range=None): + """Yields self.""" + + yield self diff --git a/pype/vendor/python/python_2/opentimelineio/schema/effect.py b/pype/vendor/python/python_2/opentimelineio/schema/effect.py new file mode 100644 index 0000000000..61eb4204fa --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/effect.py @@ -0,0 +1,130 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of Effect OTIO class.""" + +from .. import ( + core +) + +import copy + + +@core.register_type +class Effect(core.SerializableObject): + _serializable_label = "Effect.1" + + def __init__( + self, + name=None, + effect_name=None, + metadata=None + ): + super(Effect, self).__init__() + self.name = name + self.effect_name = effect_name + self.metadata = copy.deepcopy(metadata) if metadata else {} + + name = core.serializable_field( + "name", + doc="Name of this effect object. Example: 'BlurByHalfEffect'." + ) + effect_name = core.serializable_field( + "effect_name", + doc="Name of the kind of effect (example: 'Blur', 'Crop', 'Flip')." + ) + metadata = core.serializable_field( + "metadata", + dict, + doc="Metadata dictionary." + ) + + def __str__(self): + return ( + "Effect(" + "{}, " + "{}, " + "{}" + ")".format( + str(self.name), + str(self.effect_name), + str(self.metadata), + ) + ) + + def __repr__(self): + return ( + "otio.schema.Effect(" + "name={}, " + "effect_name={}, " + "metadata={}" + ")".format( + repr(self.name), + repr(self.effect_name), + repr(self.metadata), + ) + ) + + +@core.register_type +class TimeEffect(Effect): + "Base Time Effect Class" + _serializable_label = "TimeEffect.1" + pass + + +@core.register_type +class LinearTimeWarp(TimeEffect): + "A time warp that applies a linear scale across the entire clip" + _serializable_label = "LinearTimeWarp.1" + + def __init__(self, name=None, time_scalar=1, metadata=None): + Effect.__init__( + self, + name=name, + effect_name="LinearTimeWarp", + metadata=metadata + ) + self.time_scalar = time_scalar + + time_scalar = core.serializable_field( + "time_scalar", + doc="Linear time scalar applied to clip. " + "2.0 = double speed, 0.5 = half speed." + ) + + +@core.register_type +class FreezeFrame(LinearTimeWarp): + "Hold the first frame of the clip for the duration of the clip." + _serializable_label = "FreezeFrame.1" + + def __init__(self, name=None, metadata=None): + LinearTimeWarp.__init__( + self, + name=name, + time_scalar=0, + metadata=metadata + ) + self.effect_name = "FreezeFrame" diff --git a/pype/vendor/python/python_2/opentimelineio/schema/external_reference.py b/pype/vendor/python/python_2/opentimelineio/schema/external_reference.py new file mode 100644 index 0000000000..87db4d4652 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/external_reference.py @@ -0,0 +1,69 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +""" +Implementation of the ExternalReference media reference schema. +""" + +from .. import ( + core, +) + + +@core.register_type +class ExternalReference(core.MediaReference): + """Reference to media via a url, for example "file:///var/tmp/foo.mov" """ + + _serializable_label = "ExternalReference.1" + _name = "ExternalReference" + + def __init__( + self, + target_url=None, + available_range=None, + metadata=None, + ): + core.MediaReference.__init__( + self, + available_range=available_range, + metadata=metadata + ) + + self.target_url = target_url + + target_url = core.serializable_field( + "target_url", + doc=( + "URL at which this media lives. For local references, use the " + "'file://' format." + ) + ) + + def __str__(self): + return 'ExternalReference("{}")'.format(self.target_url) + + def __repr__(self): + return 'otio.schema.ExternalReference(target_url={})'.format( + repr(self.target_url) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/schema/gap.py b/pype/vendor/python/python_2/opentimelineio/schema/gap.py new file mode 100644 index 0000000000..4c8165db8f --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/gap.py @@ -0,0 +1,82 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +from .. import ( + core, + opentime, +) + +"""Gap Item - represents a transparent gap in content.""" + + +@core.register_type +class Gap(core.Item): + _serializable_label = "Gap.1" + _class_path = "schema.Gap" + + def __init__( + self, + name=None, + # note - only one of the following two arguments is accepted + # if neither is provided, source_range will be set to an empty + # TimeRange + # Duration is provided as a convienence for creating a gap of a certain + # length. IE: Gap(duration=otio.opentime.RationalTime(300, 24)) + duration=None, + source_range=None, + effects=None, + markers=None, + metadata=None, + ): + if duration and source_range: + raise RuntimeError( + "Cannot instantiate with both a source range and a duration." + ) + + if duration: + source_range = opentime.TimeRange( + opentime.RationalTime(0, duration.rate), + duration + ) + elif source_range is None: + # if neither is provided, seed TimeRange as an empty Source Range. + source_range = opentime.TimeRange() + + core.Item.__init__( + self, + name=name, + source_range=source_range, + effects=effects, + markers=markers, + metadata=metadata + ) + + @staticmethod + def visible(): + return False + + +# the original name for "gap" was "filler" - this will turn "Filler" found in +# OTIO files into Gap automatically. +core.register_type(Gap, "Filler") diff --git a/pype/vendor/python/python_2/opentimelineio/schema/generator_reference.py b/pype/vendor/python/python_2/opentimelineio/schema/generator_reference.py new file mode 100644 index 0000000000..ef1dde836e --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/generator_reference.py @@ -0,0 +1,76 @@ +""" +Generators are media references that _produce_ media rather than refer to it. +""" + +from .. import ( + core, +) + + +@core.register_type +class GeneratorReference(core.MediaReference): + """ + Base class for Generators. + + Generators are media references that become "generators" in editorial + systems. For example, color bars or a solid color. + """ + + _serializable_label = "GeneratorReference.1" + _name = "GeneratorReference" + + def __init__( + self, + name=None, + generator_kind=None, + available_range=None, + parameters=None, + metadata=None + ): + super(GeneratorReference, self).__init__( + name, + available_range, + metadata + ) + + if parameters is None: + parameters = {} + self.parameters = parameters + self.generator_kind = generator_kind + + parameters = core.serializable_field( + "parameters", + dict, + doc="Dictionary of parameters for generator." + ) + generator_kind = core.serializable_field( + "generator_kind", + required_type=type(""), + # @TODO: need to clarify if this also has an enum of supported types + # / generic + doc="Kind of generator reference, as defined by the " + "schema.generator_reference.GeneratorReferenceTypes enum." + ) + + def __str__(self): + return 'GeneratorReference("{}", "{}", {}, {})'.format( + self.name, + self.generator_kind, + self.parameters, + self.metadata + ) + + def __repr__(self): + return ( + 'otio.schema.GeneratorReference(' + 'name={}, ' + 'generator_kind={}, ' + 'parameters={}, ' + 'metadata={}' + ')'.format( + repr(self.name), + repr(self.generator_kind), + repr(self.parameters), + repr(self.metadata), + ) + ) diff --git a/pype/vendor/python/python_2/opentimelineio/schema/marker.py b/pype/vendor/python/python_2/opentimelineio/schema/marker.py new file mode 100644 index 0000000000..d8b6f1c272 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/marker.py @@ -0,0 +1,128 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Marker class. Holds metadata over regions of time.""" + +from .. import ( + core, + opentime, +) + + +class MarkerColor: + """ Enum encoding colors of markers as strings. """ + + PINK = "PINK" + RED = "RED" + ORANGE = "ORANGE" + YELLOW = "YELLOW" + GREEN = "GREEN" + CYAN = "CYAN" + BLUE = "BLUE" + PURPLE = "PURPLE" + MAGENTA = "MAGENTA" + BLACK = "BLACK" + WHITE = "WHITE" + + +@core.register_type +class Marker(core.SerializableObject): + + """ Holds metadata over time on a timeline """ + + _serializable_label = "Marker.2" + _class_path = "marker.Marker" + + def __init__( + self, + name=None, + marked_range=None, + color=MarkerColor.RED, + metadata=None, + ): + core.SerializableObject.__init__( + self, + ) + self.name = name + self.marked_range = marked_range + self.color = color + self.metadata = metadata or {} + + name = core.serializable_field("name", doc="Name of this marker.") + + marked_range = core.serializable_field( + "marked_range", + opentime.TimeRange, + "Range this marker applies to, relative to the Item this marker is " + "attached to (e.g. the Clip or Track that owns this marker)." + ) + + color = core.serializable_field( + "color", + required_type=type(MarkerColor.RED), + doc="Color string for this marker (for example: 'RED'), based on the " + "otio.schema.marker.MarkerColor enum." + ) + + # old name + range = core.deprecated_field() + + metadata = core.serializable_field( + "metadata", + dict, + "Metadata dictionary." + ) + + def __repr__(self): + return ( + "otio.schema.Marker(" + "name={}, " + "marked_range={}, " + "metadata={}" + ")".format( + repr(self.name), + repr(self.marked_range), + repr(self.metadata), + ) + ) + + def __str__(self): + return ( + "Marker(" + "{}, " + "{}, " + "{}" + ")".format( + str(self.name), + str(self.marked_range), + str(self.metadata), + ) + ) + + +@core.upgrade_function_for(Marker, 2) +def _version_one_to_two(data): + data["marked_range"] = data["range"] + del data["range"] + return data diff --git a/pype/vendor/python/python_2/opentimelineio/schema/missing_reference.py b/pype/vendor/python/python_2/opentimelineio/schema/missing_reference.py new file mode 100644 index 0000000000..88bc1862fc --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/missing_reference.py @@ -0,0 +1,43 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +""" +Implementation of the MissingReference media reference schema. +""" + +from .. import ( + core, +) + + +@core.register_type +class MissingReference(core.MediaReference): + """Represents media for which a concrete reference is missing.""" + + _serializable_label = "MissingReference.1" + _name = "MissingReference" + + @property + def is_missing_reference(self): + return True diff --git a/pype/vendor/python/python_2/opentimelineio/schema/schemadef.py b/pype/vendor/python/python_2/opentimelineio/schema/schemadef.py new file mode 100644 index 0000000000..5fb4e05abd --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/schemadef.py @@ -0,0 +1,65 @@ + +from .. import ( + core, + exceptions, + plugins, + schemadef +) + + +@core.register_type +class SchemaDef(plugins.PythonPlugin): + _serializable_label = "SchemaDef.1" + + def __init__( + self, + name=None, + execution_scope=None, + filepath=None, + ): + super(SchemaDef, self).__init__(name, execution_scope, filepath) + + def module(self): + """ + Return the module object for this schemadef plugin. + If the module hasn't already been imported, it is imported and + injected into the otio.schemadefs namespace as a side-effect. + (redefines PythonPlugin.module()) + """ + + if not self._module: + self._module = self._imported_module("schemadef") + if self.name: + schemadef._add_schemadef_module(self.name, self._module) + + return self._module + + +def available_schemadef_names(): + """Return a string list of the available schemadefs.""" + + return [str(sd.name) for sd in plugins.ActiveManifest().schemadefs] + + +def from_name(name): + """Fetch the schemadef plugin object by the name of the schema directly.""" + + try: + return plugins.ActiveManifest().from_name(name, kind_list="schemadefs") + except exceptions.NotSupportedError: + raise exceptions.NotSupportedError( + "schemadef not supported: {}, available: {}".format( + name, + available_schemadef_names() + ) + ) + + +def module_from_name(name): + """Fetch the plugin's module by the name of the schemadef. + + Will load the plugin if it has not already been loaded. Reading a file that + contains the schemadef will also trigger a load of the plugin. + """ + plugin = from_name(name) + return plugin.module() diff --git a/pype/vendor/python/python_2/opentimelineio/schema/serializable_collection.py b/pype/vendor/python/python_2/opentimelineio/schema/serializable_collection.py new file mode 100644 index 0000000000..523ea77ddb --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/serializable_collection.py @@ -0,0 +1,149 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""A serializable collection of SerializableObjects.""" + +import collections +import copy + +from .. import ( + core +) + +from . import ( + clip +) + + +@core.register_type +class SerializableCollection( + core.SerializableObject, + collections.MutableSequence +): + """A kind of composition which can hold any serializable object. + + This composition approximates the concept of a `bin` - a collection of + SerializableObjects that do not have any compositing meaning, but can + serialize to/from OTIO correctly, with metadata and a named collection. + """ + + _serializable_label = "SerializableCollection.1" + _class_path = "schema.SerializableCollection" + + def __init__( + self, + name=None, + children=None, + metadata=None, + ): + super(SerializableCollection, self).__init__() + + self.name = name + self._children = children or [] + self.metadata = copy.deepcopy(metadata) if metadata else {} + + name = core.serializable_field( + "name", + doc="SerializableCollection name." + ) + _children = core.serializable_field( + "children", + list, + "SerializableObject contained by this container." + ) + metadata = core.serializable_field( + "metadata", + dict, + doc="Metadata dictionary for this SerializableCollection." + ) + + # @{ Stringification + def __str__(self): + return "SerializableCollection({}, {}, {})".format( + str(self.name), + str(self._children), + str(self.metadata) + ) + + def __repr__(self): + return ( + "otio.{}(" + "name={}, " + "children={}, " + "metadata={}" + ")".format( + self._class_path, + repr(self.name), + repr(self._children), + repr(self.metadata) + ) + ) + # @} + + # @{ collections.MutableSequence implementation + def __getitem__(self, item): + return self._children[item] + + def __setitem__(self, key, value): + self._children[key] = value + + def insert(self, index, item): + self._children.insert(index, item) + + def __len__(self): + return len(self._children) + + def __delitem__(self, item): + del self._children[item] + # @} + + def each_child( + self, + search_range=None, + descended_from_type=core.composable.Composable + ): + for i, child in enumerate(self._children): + # filter out children who are not descended from the specified type + is_descendant = descended_from_type == core.composable.Composable + if is_descendant or isinstance(child, descended_from_type): + yield child + + # for children that are compositions, recurse into their children + if hasattr(child, "each_child"): + for valid_child in ( + c for c in child.each_child( + search_range, + descended_from_type + ) + ): + yield valid_child + + def each_clip(self, search_range=None): + return self.each_child(search_range, clip.Clip) + + +# the original name for "SerializableCollection" was "SerializeableCollection" +# this will turn this misspelling found in OTIO files into the correct instance +# automatically. +core.register_type(SerializableCollection, 'SerializeableCollection') diff --git a/pype/vendor/python/python_2/opentimelineio/schema/stack.py b/pype/vendor/python/python_2/opentimelineio/schema/stack.py new file mode 100644 index 0000000000..bf67158dc0 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/stack.py @@ -0,0 +1,120 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""A stack represents a series of composable.Composables that are arranged such +that their start times are at the same point. + +Most commonly, this would be a series of schema.Track objects that then +contain clips. The 0 time of those tracks would be coincide with the 0-time of +the stack. + +Stacks are in compositing order, with later children obscuring earlier +children. In other words, from bottom to top. If a stack has three children, +[A, B, C], C is above B which is above A. + +A stack is the length of its longest child. If a child ends before the other +children, then an earlier index child would be visible before it. +""" + +from .. import ( + core, + opentime, + exceptions +) + +from . import ( + clip +) + + +@core.register_type +class Stack(core.Composition): + _serializable_label = "Stack.1" + _composition_kind = "Stack" + _modname = "schema" + + def __init__( + self, + name=None, + children=None, + source_range=None, + markers=None, + effects=None, + metadata=None + ): + core.Composition.__init__( + self, + name=name, + children=children, + source_range=source_range, + markers=markers, + effects=effects, + metadata=metadata + ) + + def range_of_child_at_index(self, index): + try: + child = self[index] + except IndexError: + raise exceptions.NoSuchChildAtIndex(index) + + dur = child.duration() + + return opentime.TimeRange( + start_time=opentime.RationalTime(0, dur.rate), + duration=dur + ) + + def each_clip(self, search_range=None): + return self.each_child(search_range, clip.Clip) + + def available_range(self): + if len(self) == 0: + return opentime.TimeRange() + + duration = max(child.duration() for child in self) + + return opentime.TimeRange( + opentime.RationalTime(0, duration.rate), + duration=duration + ) + + def range_of_all_children(self): + child_map = {} + for i, c in enumerate(self._children): + child_map[c] = self.range_of_child_at_index(i) + return child_map + + def trimmed_range_of_child_at_index(self, index, reference_space=None): + range = self.range_of_child_at_index(index) + + if not self.source_range: + return range + + range = opentime.TimeRange( + start_time=self.source_range.start_time, + duration=min(range.duration, self.source_range.duration) + ) + + return range diff --git a/pype/vendor/python/python_2/opentimelineio/schema/timeline.py b/pype/vendor/python/python_2/opentimelineio/schema/timeline.py new file mode 100644 index 0000000000..fe7d6952ab --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/timeline.py @@ -0,0 +1,133 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implementation of the OTIO built in schema, Timeline object.""" + +import copy + +from .. import ( + core, + opentime, +) + +from . import stack, track + + +@core.register_type +class Timeline(core.SerializableObject): + _serializable_label = "Timeline.1" + + def __init__( + self, + name=None, + tracks=None, + global_start_time=None, + metadata=None, + ): + super(Timeline, self).__init__() + self.name = name + self.global_start_time = copy.deepcopy(global_start_time) + + if tracks is None: + tracks = [] + self.tracks = stack.Stack(name="tracks", children=tracks) + + self.metadata = copy.deepcopy(metadata) if metadata else {} + + name = core.serializable_field("name", doc="Name of this timeline.") + tracks = core.serializable_field( + "tracks", + core.Composition, + doc="Stack of tracks containing items." + ) + metadata = core.serializable_field( + "metadata", + dict, + "Metadata dictionary." + ) + global_start_time = core.serializable_field( + "global_start_time", + opentime.RationalTime, + doc="Global starting time value and rate of the timeline." + ) + + def __str__(self): + return 'Timeline("{}", {})'.format(str(self.name), str(self.tracks)) + + def __repr__(self): + return ( + "otio.schema.Timeline(name={}, tracks={})".format( + repr(self.name), + repr(self.tracks) + ) + ) + + def each_child(self, search_range=None, descended_from_type=core.Composable): + return self.tracks.each_child(search_range, descended_from_type) + + def each_clip(self, search_range=None): + """Return a flat list of each clip, limited to the search_range.""" + + return self.tracks.each_clip(search_range) + + def duration(self): + """Duration of this timeline.""" + + return self.tracks.duration() + + def range_of_child(self, child): + """Range of the child object contained in this timeline.""" + + return self.tracks.range_of_child(child) + + def video_tracks(self): + """ + This convenience method returns a list of the top-level video tracks in + this timeline. + """ + return [ + trck for trck + in self.tracks + if (isinstance(trck, track.Track) and + trck.kind == track.TrackKind.Video) + ] + + def audio_tracks(self): + """ + This convenience method returns a list of the top-level audio tracks in + this timeline. + """ + return [ + trck for trck + in self.tracks + if (isinstance(trck, track.Track) and + trck.kind == track.TrackKind.Audio) + ] + + +def timeline_from_clips(clips): + """Convenience for making a single track timeline from a list of clips.""" + + trck = track.Track(children=clips) + return Timeline(tracks=[trck]) diff --git a/pype/vendor/python/python_2/opentimelineio/schema/track.py b/pype/vendor/python/python_2/opentimelineio/schema/track.py new file mode 100644 index 0000000000..29b0e7f1ae --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/track.py @@ -0,0 +1,242 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Implement Track sublcass of composition.""" + +import collections + +from .. import ( + core, + opentime, +) + +from . import ( + gap, + transition, + clip, +) + + +class TrackKind: + Video = "Video" + Audio = "Audio" + + +class NeighborGapPolicy: + """ enum for deciding how to add gap when asking for neighbors """ + never = 0 + around_transitions = 1 + + +@core.register_type +class Track(core.Composition): + _serializable_label = "Track.1" + _composition_kind = "Track" + _modname = "schema" + + def __init__( + self, + name=None, + children=None, + kind=TrackKind.Video, + source_range=None, + markers=None, + effects=None, + metadata=None, + ): + core.Composition.__init__( + self, + name=name, + children=children, + source_range=source_range, + markers=markers, + effects=effects, + metadata=metadata + ) + self.kind = kind + + kind = core.serializable_field( + "kind", + doc="Composition kind (Stack, Track)" + ) + + def range_of_child_at_index(self, index): + child = self[index] + + # sum the durations of all the children leading up to the chosen one + start_time = sum( + ( + o_c.duration() + for o_c in (c for c in self[:index] if not c.overlapping()) + ), + opentime.RationalTime(value=0, rate=child.duration().rate) + ) + if isinstance(child, transition.Transition): + start_time -= child.in_offset + + return opentime.TimeRange(start_time, child.duration()) + + def trimmed_range_of_child_at_index(self, index, reference_space=None): + child_range = self.range_of_child_at_index(index) + + return self.trim_child_range(child_range) + + def handles_of_child(self, child): + """If media beyond the ends of this child are visible due to adjacent + Transitions (only applicable in a Track) then this will return the + head and tail offsets as a tuple of RationalTime objects. If no handles + are present on either side, then None is returned instead of a + RationalTime. + + Example usage + + >>> head, tail = track.handles_of_child(clip) + >>> if head: + ... print('do something') + >>> if tail: + ... print('do something else') + """ + head, tail = None, None + before, after = self.neighbors_of(child) + if isinstance(before, transition.Transition): + head = before.in_offset + if isinstance(after, transition.Transition): + tail = after.out_offset + + return head, tail + + def available_range(self): + # Sum up our child items' durations + duration = sum( + (c.duration() for c in self if isinstance(c, core.Item)), + opentime.RationalTime() + ) + + # Add the implicit gap when a Transition is at the start/end + if self and isinstance(self[0], transition.Transition): + duration += self[0].in_offset + if self and isinstance(self[-1], transition.Transition): + duration += self[-1].out_offset + + result = opentime.TimeRange( + start_time=opentime.RationalTime(0, duration.rate), + duration=duration + ) + + return result + + def each_clip(self, search_range=None, shallow_search=False): + return self.each_child(search_range, clip.Clip, shallow_search) + + def neighbors_of(self, item, insert_gap=NeighborGapPolicy.never): + """Returns the neighbors of the item as a namedtuple, (previous, next). + + Can optionally fill in gaps when transitions have no gaps next to them. + + with insert_gap == NeighborGapPolicy.never: + [A, B, C] :: neighbors_of(B) -> (A, C) + [A, B, C] :: neighbors_of(A) -> (None, B) + [A, B, C] :: neighbors_of(C) -> (B, None) + [A] :: neighbors_of(A) -> (None, None) + + with insert_gap == NeighborGapPolicy.around_transitions: + (assuming A and C are transitions) + [A, B, C] :: neighbors_of(B) -> (A, C) + [A, B, C] :: neighbors_of(A) -> (Gap, B) + [A, B, C] :: neighbors_of(C) -> (B, Gap) + [A] :: neighbors_of(A) -> (Gap, Gap) + """ + + try: + index = self.index(item) + except ValueError: + raise ValueError( + "item: {} is not in composition: {}".format( + item, + self + ) + ) + + previous, next_item = None, None + + # look before index + if index == 0: + if insert_gap == NeighborGapPolicy.around_transitions: + if isinstance(item, transition.Transition): + previous = gap.Gap( + source_range=opentime.TimeRange(duration=item.in_offset)) + elif index > 0: + previous = self[index - 1] + + if index == len(self) - 1: + if insert_gap == NeighborGapPolicy.around_transitions: + if isinstance(item, transition.Transition): + next_item = gap.Gap( + source_range=opentime.TimeRange(duration=item.out_offset)) + elif index < len(self) - 1: + next_item = self[index + 1] + + return collections.namedtuple('neighbors', ('previous', 'next'))( + previous, + next_item + ) + + def range_of_all_children(self): + """Return a dict mapping children to their range in this track.""" + + if not self._children: + return {} + + result_map = {} + + # Heuristic to guess what the rate should be set to based on the first + # thing in the track. + first_thing = self._children[0] + if isinstance(first_thing, transition.Transition): + rate = first_thing.in_offset.rate + else: + rate = first_thing.trimmed_range().duration.rate + + last_end_time = opentime.RationalTime(0, rate) + + for thing in self._children: + if isinstance(thing, transition.Transition): + result_map[thing] = opentime.TimeRange( + last_end_time - thing.in_offset, + thing.out_offset + thing.in_offset, + ) + else: + last_range = opentime.TimeRange( + last_end_time, + thing.trimmed_range().duration + ) + result_map[thing] = last_range + last_end_time = last_range.end_time_exclusive() + + return result_map + + +# the original name for "track" was "sequence" - this will turn "Sequence" +# found in OTIO files into Track automatically. +core.register_type(Track, "Sequence") diff --git a/pype/vendor/python/python_2/opentimelineio/schema/transition.py b/pype/vendor/python/python_2/opentimelineio/schema/transition.py new file mode 100644 index 0000000000..93b54ab1ab --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schema/transition.py @@ -0,0 +1,159 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Transition base class""" + +from .. import ( + opentime, + core, + exceptions, +) + +import copy + + +class TransitionTypes: + """Enum encoding types of transitions. + + This is for representing "Dissolves" and "Wipes" defined by the + multi-source effect as defined by SMPTE 258M-2004 7.6.3.2 + + Other effects are handled by the `schema.Effect` class. + """ + + # @{ SMPTE transitions. + SMPTE_Dissolve = "SMPTE_Dissolve" + # SMPTE_Wipe = "SMPTE_Wipe" -- @TODO + # @} + + # Non SMPTE transitions. + Custom = "Custom_Transition" + + +@core.register_type +class Transition(core.Composable): + """Represents a transition between two items.""" + + _serializable_label = "Transition.1" + + def __init__( + self, + name=None, + transition_type=None, + # @TODO: parameters will be added later as needed (SMPTE_Wipe will + # probably require it) + # parameters=None, + in_offset=None, + out_offset=None, + metadata=None + ): + core.Composable.__init__( + self, + name=name, + metadata=metadata + ) + + # init everything as None first, so that we will catch uninitialized + # values via exceptions + # if parameters is None: + # parameters = {} + # self.parameters = parameters + self.transition_type = transition_type + self.in_offset = copy.deepcopy(in_offset) + self.out_offset = copy.deepcopy(out_offset) + + transition_type = core.serializable_field( + "transition_type", + required_type=type(TransitionTypes.SMPTE_Dissolve), + doc="Kind of transition, as defined by the " + "schema.transition.TransitionTypes enum." + ) + # parameters = core.serializable_field( + # "parameters", + # doc="Parameters of the transition." + # ) + in_offset = core.serializable_field( + "in_offset", + required_type=opentime.RationalTime, + doc="Amount of the previous clip this transition overlaps, exclusive." + ) + out_offset = core.serializable_field( + "out_offset", + required_type=opentime.RationalTime, + doc="Amount of the next clip this transition overlaps, exclusive." + ) + + def __str__(self): + return 'Transition("{}", "{}", {}, {}, {})'.format( + self.name, + self.transition_type, + self.in_offset, + self.out_offset, + # self.parameters, + self.metadata + ) + + def __repr__(self): + return ( + 'otio.schema.Transition(' + 'name={}, ' + 'transition_type={}, ' + 'in_offset={}, ' + 'out_offset={}, ' + # 'parameters={}, ' + 'metadata={}' + ')'.format( + repr(self.name), + repr(self.transition_type), + repr(self.in_offset), + repr(self.out_offset), + # repr(self.parameters), + repr(self.metadata), + ) + ) + + @staticmethod + def overlapping(): + return True + + def duration(self): + return self.in_offset + self.out_offset + + def range_in_parent(self): + """Find and return the range of this item in the parent.""" + if not self.parent(): + raise exceptions.NotAChildError( + "No parent of {}, cannot compute range in parent.".format(self) + ) + + return self.parent().range_of_child(self) + + def trimmed_range_in_parent(self): + """Find and return the timmed range of this item in the parent.""" + if not self.parent(): + raise exceptions.NotAChildError( + "No parent of {}, cannot compute range in parent.".format(self) + ) + + return self.parent().trimmed_range_of_child(self) diff --git a/pype/vendor/python/python_2/opentimelineio/schemadef/__init__.py b/pype/vendor/python/python_2/opentimelineio/schemadef/__init__.py new file mode 100644 index 0000000000..568b3eaaa7 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/schemadef/__init__.py @@ -0,0 +1,5 @@ + +def _add_schemadef_module(name, mod): + """Insert a new module name and module object into schemadef namespace.""" + ns = globals() # the namespace dict of the schemadef package + ns[name] = mod diff --git a/pype/vendor/python/python_2/opentimelineio/test_utils.py b/pype/vendor/python/python_2/opentimelineio/test_utils.py new file mode 100644 index 0000000000..e173275ff5 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio/test_utils.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Utility assertions for OTIO Unit tests.""" + +import re + +from . import ( + adapters +) + + +class OTIOAssertions(object): + def assertJsonEqual(self, known, test_result): + """Convert to json and compare that (more readable).""" + self.maxDiff = None + + known_str = adapters.write_to_string(known, 'otio_json') + test_str = adapters.write_to_string(test_result, 'otio_json') + + def strip_trailing_decimal_zero(s): + return re.sub(r'"(value|rate)": (\d+)\.0', r'"\1": \2', s) + + self.assertMultiLineEqual( + strip_trailing_decimal_zero(known_str), + strip_trailing_decimal_zero(test_str) + ) + + def assertIsOTIOEquivalentTo(self, known, test_result): + """Test using the 'is equivalent to' method on SerializableObject""" + + self.assertTrue(known.is_equivalent_to(test_result)) diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/__init__.py b/pype/vendor/python/python_2/opentimelineio_contrib/__init__.py new file mode 100644 index 0000000000..7f7a82f46a --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/__init__.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Unsupported contrib code for OpenTimelineIO.""" + +# flake8: noqa + +from . import ( + adapters +) + +__version__ = "0.11.0" +__author__ = "Pixar Animation Studios" +__author_email__ = "opentimelineio@pixar.com" +__license__ = "Modified Apache 2.0 License" diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/__init__.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/__init__.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py new file mode 100644 index 0000000000..9e283d3747 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py @@ -0,0 +1,764 @@ +# +# Copyright 2019 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""AAF Adapter Transcriber + +Specifies how to transcribe an OpenTimelineIO file into an AAF file. +""" + +import aaf2 +import abc +import uuid +import opentimelineio as otio +import os +import copy +import re + + +AAF_PARAMETERDEF_PAN = aaf2.auid.AUID("e4962322-2267-11d3-8a4c-0050040ef7d2") +AAF_OPERATIONDEF_MONOAUDIOPAN = aaf2.auid.AUID("9d2ea893-0968-11d3-8a38-0050040ef7d2") +AAF_PARAMETERDEF_AVIDPARAMETERBYTEORDER = uuid.UUID( + "c0038672-a8cf-11d3-a05b-006094eb75cb") +AAF_PARAMETERDEF_AVIDEFFECTID = uuid.UUID( + "93994bd6-a81d-11d3-a05b-006094eb75cb") +AAF_PARAMETERDEF_AFX_FG_KEY_OPACITY_U = uuid.UUID( + "8d56813d-847e-11d5-935a-50f857c10000") +AAF_PARAMETERDEF_LEVEL = uuid.UUID("e4962320-2267-11d3-8a4c-0050040ef7d2") +AAF_VVAL_EXTRAPOLATION_ID = uuid.UUID("0e24dd54-66cd-4f1a-b0a0-670ac3a7a0b3") +AAF_OPERATIONDEF_SUBMASTER = uuid.UUID("f1db0f3d-8d64-11d3-80df-006008143e6f") + + +class AAFAdapterError(otio.exceptions.OTIOError): + pass + + +class AAFValidationError(AAFAdapterError): + pass + + +class AAFFileTranscriber(object): + """ + AAFFileTranscriber + + AAFFileTranscriber manages the file-level knowledge during a conversion from + otio to aaf. This includes keeping track of unique tapemobs and mastermobs. + """ + + def __init__(self, input_otio, aaf_file, **kwargs): + """ + AAFFileTranscriber requires an input timeline and an output pyaaf2 file handle. + + Args: + input_otio: an input OpenTimelineIO timeline + aaf_file: a pyaaf2 file handle to an output file + """ + self.aaf_file = aaf_file + self.compositionmob = self.aaf_file.create.CompositionMob() + self.compositionmob.name = input_otio.name + self.compositionmob.usage = "Usage_TopLevel" + self.aaf_file.content.mobs.append(self.compositionmob) + self._unique_mastermobs = {} + self._unique_tapemobs = {} + self._clip_mob_ids_map = _gather_clip_mob_ids(input_otio, **kwargs) + + def _unique_mastermob(self, otio_clip): + """Get a unique mastermob, identified by clip metadata mob id.""" + mob_id = self._clip_mob_ids_map.get(otio_clip) + mastermob = self._unique_mastermobs.get(mob_id) + if not mastermob: + mastermob = self.aaf_file.create.MasterMob() + mastermob.name = otio_clip.name + mastermob.mob_id = aaf2.mobid.MobID(mob_id) + self.aaf_file.content.mobs.append(mastermob) + self._unique_mastermobs[mob_id] = mastermob + return mastermob + + def _unique_tapemob(self, otio_clip): + """Get a unique tapemob, identified by clip metadata mob id.""" + mob_id = self._clip_mob_ids_map.get(otio_clip) + tapemob = self._unique_tapemobs.get(mob_id) + if not tapemob: + tapemob = self.aaf_file.create.SourceMob() + tapemob.name = otio_clip.name + tapemob.descriptor = self.aaf_file.create.ImportDescriptor() + # If the edit_rate is not an integer, we need + # to use drop frame with a nominal integer fps. + edit_rate = otio_clip.visible_range().duration.rate + timecode_fps = round(edit_rate) + tape_timecode_slot = tapemob.create_timecode_slot( + edit_rate=edit_rate, + timecode_fps=timecode_fps, + drop_frame=(edit_rate != timecode_fps) + ) + timecode_start = ( + otio_clip.media_reference.available_range.start_time.value) + timecode_length = ( + otio_clip.media_reference.available_range.duration.value) + + tape_timecode_slot.segment.start = timecode_start + tape_timecode_slot.segment.length = timecode_length + self.aaf_file.content.mobs.append(tapemob) + self._unique_tapemobs[mob_id] = tapemob + return tapemob + + def track_transcriber(self, otio_track): + """Return an appropriate _TrackTranscriber given an otio track.""" + if otio_track.kind == otio.schema.TrackKind.Video: + transcriber = VideoTrackTranscriber(self, otio_track) + elif otio_track.kind == otio.schema.TrackKind.Audio: + transcriber = AudioTrackTranscriber(self, otio_track) + else: + raise otio.exceptions.NotSupportedError( + "Unsupported track kind: {}".format(otio_track.kind)) + return transcriber + + +def validate_metadata(timeline): + """Print a check of necessary metadata requirements for an otio timeline.""" + + all_checks = [__check(timeline, "duration().rate")] + edit_rate = __check(timeline, "duration().rate").value + + for child in timeline.each_child(): + checks = [] + if isinstance(child, otio.schema.Gap): + checks = [ + __check(child, "duration().rate").equals(edit_rate) + ] + if isinstance(child, otio.schema.Clip): + checks = [ + __check(child, "duration().rate").equals(edit_rate), + __check(child, "media_reference.available_range.duration.rate" + ).equals(edit_rate), + __check(child, "media_reference.available_range.start_time.rate" + ).equals(edit_rate) + ] + if isinstance(child, otio.schema.Transition): + checks = [ + __check(child, "duration().rate").equals(edit_rate), + __check(child, "metadata['AAF']['PointList']"), + __check(child, "metadata['AAF']['OperationGroup']['Operation']" + "['DataDefinition']['Name']"), + __check(child, "metadata['AAF']['OperationGroup']['Operation']" + "['Description']"), + __check(child, "metadata['AAF']['OperationGroup']['Operation']" + "['Name']"), + __check(child, "metadata['AAF']['CutPoint']") + ] + all_checks.extend(checks) + + if any(check.errors for check in all_checks): + raise AAFValidationError("\n" + "\n".join( + sum([check.errors for check in all_checks], []))) + + +def _gather_clip_mob_ids(input_otio, + prefer_file_mob_id=False, + use_empty_mob_ids=False, + **kwargs): + """ + Create dictionary of otio clips with their corresponding mob ids. + """ + + def _from_clip_metadata(clip): + """Get the MobID from the clip.metadata.""" + return clip.metadata.get("AAF", {}).get("SourceID") + + def _from_media_reference_metadata(clip): + """Get the MobID from the media_reference.metadata.""" + return (clip.media_reference.metadata.get("AAF", {}).get("MobID") or + clip.media_reference.metadata.get("AAF", {}).get("SourceID")) + + def _from_aaf_file(clip): + """ Get the MobID from the AAF file itself.""" + mob_id = None + target_url = clip.media_reference.target_url + if os.path.isfile(target_url) and target_url.endswith("aaf"): + with aaf2.open(clip.media_reference.target_url) as aaf_file: + mastermobs = list(aaf_file.content.mastermobs()) + if len(mastermobs) == 1: + mob_id = mastermobs[0].mob_id + return mob_id + + def _generate_empty_mobid(clip): + """Generate a meaningless MobID.""" + return aaf2.mobid.MobID.new() + + strategies = [ + _from_clip_metadata, + _from_media_reference_metadata, + _from_aaf_file + ] + + if prefer_file_mob_id: + strategies.remove(_from_aaf_file) + strategies.insert(0, _from_aaf_file) + + if use_empty_mob_ids: + strategies.append(_generate_empty_mobid) + + clip_mob_ids = {} + + for otio_clip in input_otio.each_clip(): + for strategy in strategies: + mob_id = strategy(otio_clip) + if mob_id: + clip_mob_ids[otio_clip] = mob_id + break + else: + raise AAFAdapterError("Cannot find mob ID for clip {}".format(otio_clip)) + + return clip_mob_ids + + +def _stackify_nested_groups(timeline): + """ + Ensure that all nesting in a given timeline is in a stack container. + This conforms with how AAF thinks about nesting, there needs + to be an outer container, even if it's just one object. + """ + copied = copy.deepcopy(timeline) + for track in copied.tracks: + for i, child in enumerate(track.each_child()): + is_nested = isinstance(child, otio.schema.Track) + is_parent_in_stack = isinstance(child.parent(), otio.schema.Stack) + if is_nested and not is_parent_in_stack: + stack = otio.schema.Stack() + track.remove(child) + stack.append(child) + track.insert(i, stack) + return copied + + +class _TrackTranscriber(object): + """ + _TrackTranscriber is the base class for the conversion of a given otio track. + + _TrackTranscriber is not meant to be used by itself. It provides the common + functionality to inherit from. We need an abstract base class because Audio and + Video are handled differently. + """ + __metaclass__ = abc.ABCMeta + + def __init__(self, root_file_transcriber, otio_track): + """ + _TrackTranscriber + + Args: + root_file_transcriber: the corresponding 'parent' AAFFileTranscriber object + otio_track: the given otio_track to convert + """ + self.root_file_transcriber = root_file_transcriber + self.compositionmob = root_file_transcriber.compositionmob + self.aaf_file = root_file_transcriber.aaf_file + self.otio_track = otio_track + self.edit_rate = next(self.otio_track.each_child()).duration().rate + self.timeline_mobslot, self.sequence = self._create_timeline_mobslot() + self.timeline_mobslot.name = self.otio_track.name + + def transcribe(self, otio_child): + """Transcribe otio child to corresponding AAF object""" + if isinstance(otio_child, otio.schema.Gap): + filler = self.aaf_filler(otio_child) + return filler + elif isinstance(otio_child, otio.schema.Transition): + transition = self.aaf_transition(otio_child) + return transition + elif isinstance(otio_child, otio.schema.Clip): + source_clip = self.aaf_sourceclip(otio_child) + return source_clip + elif isinstance(otio_child, otio.schema.Track): + sequence = self.aaf_sequence(otio_child) + return sequence + elif isinstance(otio_child, otio.schema.Stack): + operation_group = self.aaf_operation_group(otio_child) + return operation_group + else: + raise otio.exceptions.NotSupportedError( + "Unsupported otio child type: {}".format(type(otio_child))) + + @property + @abc.abstractmethod + def media_kind(self): + """Return the string for what kind of track this is.""" + pass + + @property + @abc.abstractmethod + def _master_mob_slot_id(self): + """ + Return the MasterMob Slot ID for the corresponding track media kind + """ + # MasterMob's and MasterMob slots have to be unique. We handle unique + # MasterMob's with _unique_mastermob(). We also need to protect against + # duplicate MasterMob slots. As of now, we mandate all picture clips to + # be created in MasterMob slot 1 and all sound clips to be created in + # MasterMob slot 2. While this is a little inadequate, it works for now + pass + + @abc.abstractmethod + def _create_timeline_mobslot(self): + """ + Return a timeline_mobslot and sequence for this track. + + In AAF, a TimelineMobSlot is a container for the Sequence. A Sequence is + analogous to an otio track. + + Returns: + Returns a tuple of (TimelineMobSlot, Sequence) + """ + pass + + @abc.abstractmethod + def default_descriptor(self, otio_clip): + pass + + @abc.abstractmethod + def _transition_parameters(self): + pass + + def aaf_filler(self, otio_gap): + """Convert an otio Gap into an aaf Filler""" + length = otio_gap.visible_range().duration.value + filler = self.aaf_file.create.Filler(self.media_kind, length) + return filler + + def aaf_sourceclip(self, otio_clip): + """Convert an otio Clip into an aaf SourceClip""" + tapemob, tapemob_slot = self._create_tapemob(otio_clip) + filemob, filemob_slot = self._create_filemob(otio_clip, tapemob, tapemob_slot) + mastermob, mastermob_slot = self._create_mastermob(otio_clip, + filemob, + filemob_slot) + + # We need both `start_time` and `duration` + # Here `start` is the offset between `first` and `in` values. + + offset = (otio_clip.visible_range().start_time - + otio_clip.available_range().start_time) + start = offset.value + length = otio_clip.visible_range().duration.value + + compmob_clip = self.compositionmob.create_source_clip( + slot_id=self.timeline_mobslot.slot_id, + start=start, + length=length, + media_kind=self.media_kind) + compmob_clip.mob = mastermob + compmob_clip.slot = mastermob_slot + compmob_clip.slot_id = mastermob_slot.slot_id + return compmob_clip + + def aaf_transition(self, otio_transition): + """Convert an otio Transition into an aaf Transition""" + if (otio_transition.transition_type != + otio.schema.transition.TransitionTypes.SMPTE_Dissolve): + print( + "Unsupported transition type: {}".format( + otio_transition.transition_type)) + return None + + transition_params, varying_value = self._transition_parameters() + + interpolation_def = self.aaf_file.create.InterpolationDef( + aaf2.misc.LinearInterp, "LinearInterp", "Linear keyframe interpolation") + self.aaf_file.dictionary.register_def(interpolation_def) + varying_value["Interpolation"].value = ( + self.aaf_file.dictionary.lookup_interperlationdef("LinearInterp")) + + pointlist = otio_transition.metadata["AAF"]["PointList"] + + c1 = self.aaf_file.create.ControlPoint() + c1["EditHint"].value = "Proportional" + c1.value = pointlist[0]["Value"] + c1.time = pointlist[0]["Time"] + + c2 = self.aaf_file.create.ControlPoint() + c2["EditHint"].value = "Proportional" + c2.value = pointlist[1]["Value"] + c2.time = pointlist[1]["Time"] + + varying_value["PointList"].extend([c1, c2]) + + op_group_metadata = otio_transition.metadata["AAF"]["OperationGroup"] + effect_id = op_group_metadata["Operation"].get("Identification") + is_time_warp = op_group_metadata["Operation"].get("IsTimeWarp") + by_pass = op_group_metadata["Operation"].get("Bypass") + number_inputs = op_group_metadata["Operation"].get("NumberInputs") + operation_category = op_group_metadata["Operation"].get("OperationCategory") + data_def_name = op_group_metadata["Operation"]["DataDefinition"]["Name"] + data_def = self.aaf_file.dictionary.lookup_datadef(str(data_def_name)) + description = op_group_metadata["Operation"]["Description"] + op_def_name = otio_transition.metadata["AAF"][ + "OperationGroup" + ]["Operation"]["Name"] + + # Create OperationDefinition + op_def = self.aaf_file.create.OperationDef(uuid.UUID(effect_id), op_def_name) + self.aaf_file.dictionary.register_def(op_def) + op_def.media_kind = self.media_kind + datadef = self.aaf_file.dictionary.lookup_datadef(self.media_kind) + op_def["IsTimeWarp"].value = is_time_warp + op_def["Bypass"].value = by_pass + op_def["NumberInputs"].value = number_inputs + op_def["OperationCategory"].value = str(operation_category) + op_def["ParametersDefined"].extend(transition_params) + op_def["DataDefinition"].value = data_def + op_def["Description"].value = str(description) + + # Create OperationGroup + length = otio_transition.duration().value + operation_group = self.aaf_file.create.OperationGroup(op_def, length) + operation_group["DataDefinition"].value = datadef + operation_group["Parameters"].append(varying_value) + + # Create Transition + transition = self.aaf_file.create.Transition(self.media_kind, length) + transition["OperationGroup"].value = operation_group + transition["CutPoint"].value = otio_transition.metadata["AAF"]["CutPoint"] + transition["DataDefinition"].value = datadef + return transition + + def aaf_sequence(self, otio_track): + """Convert an otio Track into an aaf Sequence""" + sequence = self.aaf_file.create.Sequence(media_kind=self.media_kind) + length = 0 + for nested_otio_child in otio_track: + result = self.transcribe(nested_otio_child) + length += result.length + sequence.components.append(result) + sequence.length = length + return sequence + + def aaf_operation_group(self, otio_stack): + """ + Create and return an OperationGroup which will contain other AAF objects + to support OTIO nesting + """ + # Create OperationDefinition + op_def = self.aaf_file.create.OperationDef(AAF_OPERATIONDEF_SUBMASTER, + "Submaster") + self.aaf_file.dictionary.register_def(op_def) + op_def.media_kind = self.media_kind + datadef = self.aaf_file.dictionary.lookup_datadef(self.media_kind) + + # These values are necessary for pyaaf2 OperationDefinitions + op_def["IsTimeWarp"].value = False + op_def["Bypass"].value = 0 + op_def["NumberInputs"].value = -1 + op_def["OperationCategory"].value = "OperationCategory_Effect" + op_def["DataDefinition"].value = datadef + + # Create OperationGroup + operation_group = self.aaf_file.create.OperationGroup(op_def) + operation_group.media_kind = self.media_kind + operation_group["DataDefinition"].value = datadef + + length = 0 + for nested_otio_child in otio_stack: + result = self.transcribe(nested_otio_child) + length += result.length + operation_group.segments.append(result) + operation_group.length = length + return operation_group + + def _create_tapemob(self, otio_clip): + """ + Return a physical sourcemob for an otio Clip based on the MobID. + + Returns: + Returns a tuple of (TapeMob, TapeMobSlot) + """ + tapemob = self.root_file_transcriber._unique_tapemob(otio_clip) + tapemob_slot = tapemob.create_empty_slot(self.edit_rate, self.media_kind) + tapemob_slot.segment.length = ( + otio_clip.media_reference.available_range.duration.value) + return tapemob, tapemob_slot + + def _create_filemob(self, otio_clip, tapemob, tapemob_slot): + """ + Return a file sourcemob for an otio Clip. Needs a tapemob and tapemob slot. + + Returns: + Returns a tuple of (FileMob, FileMobSlot) + """ + filemob = self.aaf_file.create.SourceMob() + self.aaf_file.content.mobs.append(filemob) + + filemob.descriptor = self.default_descriptor(otio_clip) + filemob_slot = filemob.create_timeline_slot(self.edit_rate) + filemob_clip = filemob.create_source_clip( + slot_id=filemob_slot.slot_id, + length=tapemob_slot.segment.length, + media_kind=tapemob_slot.segment.media_kind) + filemob_clip.mob = tapemob + filemob_clip.slot = tapemob_slot + filemob_clip.slot_id = tapemob_slot.slot_id + filemob_slot.segment = filemob_clip + return filemob, filemob_slot + + def _create_mastermob(self, otio_clip, filemob, filemob_slot): + """ + Return a mastermob for an otio Clip. Needs a filemob and filemob slot. + + Returns: + Returns a tuple of (MasterMob, MasterMobSlot) + """ + mastermob = self.root_file_transcriber._unique_mastermob(otio_clip) + timecode_length = otio_clip.media_reference.available_range.duration.value + + try: + mastermob_slot = mastermob.slot_at(self._master_mob_slot_id) + except IndexError: + mastermob_slot = ( + mastermob.create_timeline_slot(edit_rate=self.edit_rate, + slot_id=self._master_mob_slot_id)) + mastermob_clip = mastermob.create_source_clip( + slot_id=mastermob_slot.slot_id, + length=timecode_length, + media_kind=self.media_kind) + mastermob_clip.mob = filemob + mastermob_clip.slot = filemob_slot + mastermob_clip.slot_id = filemob_slot.slot_id + mastermob_slot.segment = mastermob_clip + return mastermob, mastermob_slot + + +class VideoTrackTranscriber(_TrackTranscriber): + """Video track kind specialization of TrackTranscriber.""" + + @property + def media_kind(self): + return "picture" + + @property + def _master_mob_slot_id(self): + return 1 + + def _create_timeline_mobslot(self): + """ + Create a Sequence container (TimelineMobSlot) and Sequence. + + TimelineMobSlot --> Sequence + """ + timeline_mobslot = self.compositionmob.create_timeline_slot( + edit_rate=self.edit_rate) + sequence = self.aaf_file.create.Sequence(media_kind=self.media_kind) + timeline_mobslot.segment = sequence + return timeline_mobslot, sequence + + def default_descriptor(self, otio_clip): + # TODO: Determine if these values are the correct, and if so, + # maybe they should be in the AAF metadata + descriptor = self.aaf_file.create.CDCIDescriptor() + descriptor["ComponentWidth"].value = 8 + descriptor["HorizontalSubsampling"].value = 2 + descriptor["ImageAspectRatio"].value = "16/9" + descriptor["StoredWidth"].value = 1920 + descriptor["StoredHeight"].value = 1080 + descriptor["FrameLayout"].value = "FullFrame" + descriptor["VideoLineMap"].value = [42, 0] + descriptor["SampleRate"].value = 24 + descriptor["Length"].value = 1 + return descriptor + + def _transition_parameters(self): + """ + Return video transition parameters + """ + # Create ParameterDef for AvidParameterByteOrder + byteorder_typedef = self.aaf_file.dictionary.lookup_typedef("aafUInt16") + param_byteorder = self.aaf_file.create.ParameterDef( + AAF_PARAMETERDEF_AVIDPARAMETERBYTEORDER, + "AvidParameterByteOrder", + "", + byteorder_typedef) + self.aaf_file.dictionary.register_def(param_byteorder) + + # Create ParameterDef for AvidEffectID + avid_effect_typdef = self.aaf_file.dictionary.lookup_typedef("AvidBagOfBits") + param_effect_id = self.aaf_file.create.ParameterDef( + AAF_PARAMETERDEF_AVIDEFFECTID, + "AvidEffectID", + "", + avid_effect_typdef) + self.aaf_file.dictionary.register_def(param_effect_id) + + # Create ParameterDef for AFX_FG_KEY_OPACITY_U + opacity_param_def = self.aaf_file.dictionary.lookup_typedef("Rational") + opacity_param = self.aaf_file.create.ParameterDef( + AAF_PARAMETERDEF_AFX_FG_KEY_OPACITY_U, + "AFX_FG_KEY_OPACITY_U", + "", + opacity_param_def) + self.aaf_file.dictionary.register_def(opacity_param) + + # Create VaryingValue + opacity_u = self.aaf_file.create.VaryingValue() + opacity_u.parameterdef = self.aaf_file.dictionary.lookup_parameterdef( + "AFX_FG_KEY_OPACITY_U") + opacity_u["VVal_Extrapolation"].value = AAF_VVAL_EXTRAPOLATION_ID + opacity_u["VVal_FieldCount"].value = 1 + + return [param_byteorder, param_effect_id], opacity_u + + +class AudioTrackTranscriber(_TrackTranscriber): + """Audio track kind specialization of TrackTranscriber.""" + + @property + def media_kind(self): + return "sound" + + @property + def _master_mob_slot_id(self): + return 2 + + def aaf_sourceclip(self, otio_clip): + # Parameter Definition + typedef = self.aaf_file.dictionary.lookup_typedef("Rational") + param_def = self.aaf_file.create.ParameterDef(AAF_PARAMETERDEF_PAN, + "Pan", + "Pan", + typedef) + self.aaf_file.dictionary.register_def(param_def) + interp_def = self.aaf_file.create.InterpolationDef(aaf2.misc.LinearInterp, + "LinearInterp", + "LinearInterp") + self.aaf_file.dictionary.register_def(interp_def) + # PointList + length = otio_clip.duration().value + c1 = self.aaf_file.create.ControlPoint() + c1["ControlPointSource"].value = 2 + c1["Time"].value = aaf2.rational.AAFRational("0/{}".format(length)) + c1["Value"].value = 0 + c2 = self.aaf_file.create.ControlPoint() + c2["ControlPointSource"].value = 2 + c2["Time"].value = aaf2.rational.AAFRational("{}/{}".format(length - 1, length)) + c2["Value"].value = 0 + varying_value = self.aaf_file.create.VaryingValue() + varying_value.parameterdef = param_def + varying_value["Interpolation"].value = interp_def + varying_value["PointList"].extend([c1, c2]) + opgroup = self.timeline_mobslot.segment + opgroup.parameters.append(varying_value) + + return super(AudioTrackTranscriber, self).aaf_sourceclip(otio_clip) + + def _create_timeline_mobslot(self): + """ + Create a Sequence container (TimelineMobSlot) and Sequence. + Sequence needs to be in an OperationGroup. + + TimelineMobSlot --> OperationGroup --> Sequence + """ + # TimelineMobSlot + timeline_mobslot = self.compositionmob.create_sound_slot( + edit_rate=self.edit_rate) + # OperationDefinition + opdef = self.aaf_file.create.OperationDef(AAF_OPERATIONDEF_MONOAUDIOPAN, + "Audio Pan") + opdef.media_kind = self.media_kind + opdef["NumberInputs"].value = 1 + self.aaf_file.dictionary.register_def(opdef) + # OperationGroup + total_length = sum([t.duration().value for t in self.otio_track]) + opgroup = self.aaf_file.create.OperationGroup(opdef) + opgroup.media_kind = self.media_kind + opgroup.length = total_length + timeline_mobslot.segment = opgroup + # Sequence + sequence = self.aaf_file.create.Sequence(media_kind=self.media_kind) + sequence.length = total_length + opgroup.segments.append(sequence) + return timeline_mobslot, sequence + + def default_descriptor(self, otio_clip): + descriptor = self.aaf_file.create.PCMDescriptor() + descriptor["AverageBPS"].value = 96000 + descriptor["BlockAlign"].value = 2 + descriptor["QuantizationBits"].value = 16 + descriptor["AudioSamplingRate"].value = 48000 + descriptor["Channels"].value = 1 + descriptor["SampleRate"].value = 48000 + descriptor["Length"].value = ( + otio_clip.media_reference.available_range.duration.value) + return descriptor + + def _transition_parameters(self): + """ + Return audio transition parameters + """ + # Create ParameterDef for ParameterDef_Level + def_level_typedef = self.aaf_file.dictionary.lookup_typedef("Rational") + param_def_level = self.aaf_file.create.ParameterDef(AAF_PARAMETERDEF_LEVEL, + "ParameterDef_Level", + "", + def_level_typedef) + self.aaf_file.dictionary.register_def(param_def_level) + + # Create VaryingValue + level = self.aaf_file.create.VaryingValue() + level.parameterdef = ( + self.aaf_file.dictionary.lookup_parameterdef("ParameterDef_Level")) + + return [param_def_level], level + + +class __check(object): + """ + __check is a private helper class that safely gets values given to check + for existence and equality + """ + + def __init__(self, obj, tokenpath): + self.orig = obj + self.value = obj + self.errors = [] + self.tokenpath = tokenpath + try: + for token in re.split(r"[\.\[]", tokenpath): + if token.endswith("()"): + self.value = getattr(self.value, token.replace("()", ""))() + elif "]" in token: + self.value = self.value[token.strip("[]'\"")] + else: + self.value = getattr(self.value, token) + except Exception as e: + self.value = None + self.errors.append("{}{} {}.{} does not exist, {}".format( + self.orig.name if hasattr(self.orig, "name") else "", + type(self.orig), + type(self.orig).__name__, + self.tokenpath, e)) + + def equals(self, val): + """Check if the retrieved value is equal to a given value.""" + if self.value is not None and self.value != val: + self.errors.append( + "{}{} {}.{} not equal to {} (expected) != {} (actual)".format( + self.orig.name if hasattr(self.orig, "name") else "", + type(self.orig), + type(self.orig).__name__, self.tokenpath, val, self.value)) + return self diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/advanced_authoring_format.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/advanced_authoring_format.py new file mode 100644 index 0000000000..6c21ea3e55 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/advanced_authoring_format.py @@ -0,0 +1,979 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO Advanced Authoring Format (AAF) Adapter + +Depending on if/where PyAAF is installed, you may need to set this env var: + OTIO_AAF_PYTHON_LIB - should point at the PyAAF module. +""" + +import os +import sys +import numbers +import copy +from collections import Iterable +import opentimelineio as otio + +lib_path = os.environ.get("OTIO_AAF_PYTHON_LIB") +if lib_path and lib_path not in sys.path: + sys.path.insert(0, lib_path) + +import aaf2 # noqa: E402 +import aaf2.content # noqa: E402 +import aaf2.mobs # noqa: E402 +import aaf2.components # noqa: E402 +import aaf2.core # noqa: E402 +from opentimelineio_contrib.adapters.aaf_adapter import aaf_writer # noqa: E402 + + +debug = False +__names = set() + + +def _get_parameter(item, parameter_name): + values = dict((value.name, value) for value in item.parameters.value) + return values.get(parameter_name) + + +def _get_name(item): + if isinstance(item, aaf2.components.SourceClip): + try: + return item.mob.name or "Untitled SourceClip" + except AttributeError: + # Some AAFs produce this error: + # RuntimeError: failed with [-2146303738]: mob not found + return "SourceClip Missing Mob?" + if hasattr(item, 'name'): + name = item.name + if name: + return name + return _get_class_name(item) + + +def _get_class_name(item): + if hasattr(item, "class_name"): + return item.class_name + else: + return item.__class__.__name__ + + +def _transcribe_property(prop): + # XXX: The unicode type doesn't exist in Python 3 (all strings are unicode) + # so we have to use type(u"") which works in both Python 2 and 3. + if isinstance(prop, (str, type(u""), numbers.Integral, float)): + return prop + + elif isinstance(prop, list): + result = {} + for child in prop: + if hasattr(child, "name") and hasattr(child, "value"): + result[child.name] = _transcribe_property(child.value) + else: + # @TODO: There may be more properties that we might want also. + # If you want to see what is being skipped, turn on debug. + if debug: + debug_message = \ + "Skipping unrecognized property: {} of parent {}" + print(debug_message.format(child, prop)) + return result + elif hasattr(prop, "properties"): + result = {} + for child in prop.properties(): + result[child.name] = _transcribe_property(child.value) + return result + else: + return str(prop) + + +def _find_timecode_mobs(item): + mobs = [item.mob] + + for c in item.walk(): + if isinstance(c, aaf2.components.SourceClip): + mob = c.mob + if mob: + mobs.append(mob) + else: + continue + else: + # This could be 'EssenceGroup', 'Pulldown' or other segment + # subclasses + # See also: https://jira.pixar.com/browse/SE-3457 + # For example: + # An EssenceGroup is a Segment that has one or more + # alternate choices, each of which represent different variations + # of one actual piece of content. + # According to the AAF Object Specification and Edit Protocol + # documents: + # "Typically the different representations vary in essence format, + # compression, or frame size. The application is responsible for + # choosing the appropriate implementation of the essence." + # It also says they should all have the same length, but + # there might be nested Sequences inside which we're not attempting + # to handle here (yet). We'll need a concrete example to ensure + # we're doing the right thing. + # TODO: Is the Timecode for an EssenceGroup correct? + # TODO: Try CountChoices() and ChoiceAt(i) + # For now, lets just skip it. + continue + + return mobs + + +def _extract_timecode_info(mob): + """Given a mob with a single timecode slot, return the timecode and length + in that slot as a tuple + """ + timecodes = [slot.segment for slot in mob.slots + if isinstance(slot.segment, aaf2.components.Timecode)] + + if len(timecodes) == 1: + timecode = timecodes[0] + timecode_start = timecode.getvalue('Start') + timecode_length = timecode.getvalue('Length') + + if timecode_start is None or timecode_length is None: + raise otio.exceptions.NotSupportedError( + "Unexpected timecode value(s) in mob named: `{}`." + " `Start`: {}, `Length`: {}".format(mob.name, + timecode_start, + timecode_length) + ) + + return timecode_start, timecode_length + elif len(timecodes) > 1: + raise otio.exceptions.NotSupportedError( + "Error: mob has more than one timecode slots, this is not" + " currently supported by the AAF adapter. found: {} slots, " + " mob name is: '{}'".format(len(timecodes), mob.name) + ) + else: + return None + + +def _add_child(parent, child, source): + if child is None: + if debug: + print("Adding null child? {}".format(source)) + elif isinstance(child, otio.schema.Marker): + parent.markers.append(child) + else: + parent.append(child) + + +def _transcribe(item, parents, editRate, masterMobs): + result = None + metadata = {} + + # First lets grab some standard properties that are present on + # many types of AAF objects... + metadata["Name"] = _get_name(item) + metadata["ClassName"] = _get_class_name(item) + + # Some AAF objects (like TimelineMobSlot) have an edit rate + # which should be used for all of the object's children. + # We will pass it on to any recursive calls to _transcribe() + if hasattr(item, "edit_rate"): + editRate = float(item.edit_rate) + + if isinstance(item, aaf2.components.Component): + metadata["Length"] = item.length + + if isinstance(item, aaf2.core.AAFObject): + for prop in item.properties(): + if hasattr(prop, 'name') and hasattr(prop, 'value'): + key = str(prop.name) + value = prop.value + metadata[key] = _transcribe_property(value) + + # Now we will use the item's class to determine which OTIO type + # to transcribe into. Note that the order of this if/elif/... chain + # is important, because the class hierarchy of AAF objects is more + # complex than OTIO. + + if isinstance(item, aaf2.content.ContentStorage): + result = otio.schema.SerializableCollection() + + # Gather all the Master Mobs, so we can find them later by MobID + # when we parse the SourceClips in the composition + if masterMobs is None: + masterMobs = {} + for mob in item.mastermobs(): + child = _transcribe(mob, parents + [item], editRate, masterMobs) + if child is not None: + mobID = child.metadata.get("AAF", {}).get("MobID") + masterMobs[mobID] = child + + for mob in item.compositionmobs(): + child = _transcribe(mob, parents + [item], editRate, masterMobs) + _add_child(result, child, mob) + + elif isinstance(item, aaf2.mobs.Mob): + result = otio.schema.Timeline() + + for slot in item.slots: + track = _transcribe(slot, parents + [item], editRate, masterMobs) + _add_child(result.tracks, track, slot) + + # Use a heuristic to find the starting timecode from + # this track and use it for the Timeline's global_start_time + start_time = _find_timecode_track_start(track) + if start_time: + result.global_start_time = start_time + + elif isinstance(item, aaf2.components.SourceClip): + result = otio.schema.Clip() + + # Evidently the last mob is the one with the timecode + mobs = _find_timecode_mobs(item) + # Get the Timecode start and length values + last_mob = mobs[-1] if mobs else None + timecode_info = _extract_timecode_info(last_mob) if last_mob else None + + source_start = int(metadata.get("StartTime", "0")) + source_length = item.length + media_start = source_start + media_length = item.length + + if timecode_info: + media_start, media_length = timecode_info + source_start += media_start + + # The goal here is to find a source range. Actual editorial opinions are found on SourceClips in the + # CompositionMobs. To figure out whether this clip is directly in the CompositionMob, we detect if our + # parent mobs are only CompositionMobs. If they were anything else - a MasterMob, a SourceMob, we would + # know that this is in some indirect relationship. + parent_mobs = filter(lambda parent: isinstance(parent, aaf2.mobs.Mob), parents) + is_directly_in_composition = all(isinstance(mob, aaf2.mobs.CompositionMob) for mob in parent_mobs) + if is_directly_in_composition: + result.source_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(source_start, editRate), + otio.opentime.RationalTime(source_length, editRate) + ) + + # The goal here is to find an available range. Media ranges are stored in the related MasterMob, and there + # should only be one - hence the name "Master" mob. Somewhere down our chain (either a child or our parents) + # is a MasterMob. For SourceClips in the CompositionMob, it is our child. For everything else, it is a + # previously encountered parent. Find the MasterMob in our chain, and then extract the information from that. + child_mastermob = item.mob if isinstance(item.mob, aaf2.mobs.MasterMob) else None + parent_mastermobs = [parent for parent in parents if isinstance(parent, aaf2.mobs.MasterMob)] + parent_mastermob = parent_mastermobs[0] if len(parent_mastermobs) > 1 else None + mastermob = child_mastermob or parent_mastermob or None + + if mastermob: + media = otio.schema.MissingReference() + media.available_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(media_start, editRate), + otio.opentime.RationalTime(media_length, editRate) + ) + # copy the metadata from the master into the media_reference + mastermob_child = masterMobs.get(str(mastermob.mob_id)) + media.metadata["AAF"] = mastermob_child.metadata.get("AAF", {}) + result.media_reference = media + + elif isinstance(item, aaf2.components.Transition): + result = otio.schema.Transition() + + # Does AAF support anything else? + result.transition_type = otio.schema.TransitionTypes.SMPTE_Dissolve + + # Extract value and time attributes of both ControlPoints used for + # creating AAF Transition objects + varying_value = None + for param in item.getvalue('OperationGroup').parameters: + if isinstance(param, aaf2.misc.VaryingValue): + varying_value = param + break + + if varying_value is not None: + for control_point in varying_value.getvalue('PointList'): + value = control_point.value + time = control_point.time + metadata.setdefault('PointList', []).append({'Value': value, + 'Time': time}) + + in_offset = int(metadata.get("CutPoint", "0")) + out_offset = item.length - in_offset + result.in_offset = otio.opentime.RationalTime(in_offset, editRate) + result.out_offset = otio.opentime.RationalTime(out_offset, editRate) + + elif isinstance(item, aaf2.components.Filler): + result = otio.schema.Gap() + + length = item.length + result.source_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(0, editRate), + otio.opentime.RationalTime(length, editRate) + ) + + elif isinstance(item, aaf2.components.NestedScope): + # TODO: Is this the right class? + result = otio.schema.Stack() + + for slot in item.slots: + child = _transcribe(slot, parents + [item], editRate, masterMobs) + _add_child(result, child, slot) + + elif isinstance(item, aaf2.components.Sequence): + result = otio.schema.Track() + + for component in item.components: + child = _transcribe(component, parents + [item], editRate, masterMobs) + _add_child(result, child, component) + + elif isinstance(item, aaf2.components.OperationGroup): + result = _transcribe_operation_group( + item, parents, metadata, editRate, masterMobs + ) + + elif isinstance(item, aaf2.mobslots.TimelineMobSlot): + result = otio.schema.Track() + + child = _transcribe(item.segment, parents + [item], editRate, masterMobs) + _add_child(result, child, item.segment) + + elif isinstance(item, aaf2.mobslots.MobSlot): + result = otio.schema.Track() + + child = _transcribe(item.segment, parents + [item], editRate, masterMobs) + _add_child(result, child, item.segment) + + elif isinstance(item, aaf2.components.Timecode): + pass + + elif isinstance(item, aaf2.components.Pulldown): + pass + + elif isinstance(item, aaf2.components.EdgeCode): + pass + + elif isinstance(item, aaf2.components.ScopeReference): + # TODO: is this like FILLER? + + result = otio.schema.Gap() + + length = item.length + result.source_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(0, editRate), + otio.opentime.RationalTime(length, editRate) + ) + + elif isinstance(item, aaf2.components.DescriptiveMarker): + + # Markers come in on their own separate Track. + # TODO: We should consolidate them onto the same track(s) as the clips + # result = otio.schema.Marker() + pass + + elif isinstance(item, aaf2.components.Selector): + # If you mute a clip in media composer, it becomes one of these in the + # AAF. + result = _transcribe( + item.getvalue("Selected"), + parents + [item], + editRate, + masterMobs + ) + + alternates = [ + _transcribe(alt, parents + [item], editRate, masterMobs) + for alt in item.getvalue("Alternates") + ] + + # muted case -- if there is only one item its muted, otherwise its + # a multi cam thing + if alternates and len(alternates) == 1: + metadata['muted_clip'] = True + result.name = str(alternates[0].name) + "_MUTED" + + metadata['alternates'] = alternates + + # @TODO: There are a bunch of other AAF object types that we will + # likely need to add support for. I'm leaving this code here to help + # future efforts to extract the useful information out of these. + + # elif isinstance(item, aaf.storage.File): + # self.extendChildItems([item.header]) + + # elif isinstance(item, aaf.storage.Header): + # self.extendChildItems([item.storage()]) + # self.extendChildItems([item.dictionary()]) + + # elif isinstance(item, aaf.dictionary.Dictionary): + # l = [] + # l.append(DummyItem(list(item.class_defs()), 'ClassDefs')) + # l.append(DummyItem(list(item.codec_defs()), 'CodecDefs')) + # l.append(DummyItem(list(item.container_defs()), 'ContainerDefs')) + # l.append(DummyItem(list(item.data_defs()), 'DataDefs')) + # l.append(DummyItem(list(item.interpolation_defs()), + # 'InterpolationDefs')) + # l.append(DummyItem(list(item.klvdata_defs()), 'KLVDataDefs')) + # l.append(DummyItem(list(item.operation_defs()), 'OperationDefs')) + # l.append(DummyItem(list(item.parameter_defs()), 'ParameterDefs')) + # l.append(DummyItem(list(item.plugin_defs()), 'PluginDefs')) + # l.append(DummyItem(list(item.taggedvalue_defs()), 'TaggedValueDefs')) + # l.append(DummyItem(list(item.type_defs()), 'TypeDefs')) + # self.extendChildItems(l) + # + # elif isinstance(item, pyaaf.AxSelector): + # self.extendChildItems(list(item.EnumAlternateSegments())) + # + # elif isinstance(item, pyaaf.AxScopeReference): + # #print item, item.GetRelativeScope(),item.GetRelativeSlot() + # pass + # + # elif isinstance(item, pyaaf.AxEssenceGroup): + # segments = [] + # + # for i in xrange(item.CountChoices()): + # choice = item.GetChoiceAt(i) + # segments.append(choice) + # self.extendChildItems(segments) + # + # elif isinstance(item, pyaaf.AxProperty): + # self.properties['Value'] = str(item.GetValue()) + + elif isinstance(item, Iterable): + result = otio.schema.SerializableCollection() + for child in item: + result.append( + _transcribe( + child, + parents + [item], + editRate, + masterMobs + ) + ) + else: + # For everything else, we just ignore it. + # To see what is being ignored, turn on the debug flag + if debug: + print("SKIPPING: {}: {} -- {}".format(type(item), item, result)) + + # Did we get anything? If not, we're done + if result is None: + return None + + # Okay, now we've turned the AAF thing into an OTIO result + # There's a bit more we can do before we're ready to return the result. + + # If we didn't get a name yet, use the one we have in metadata + if result.name is None: + result.name = metadata["Name"] + + # Attach the AAF metadata + if not result.metadata: + result.metadata = {} + result.metadata["AAF"] = metadata + + # Double check that we got the length we expected + if isinstance(result, otio.core.Item): + length = metadata.get("Length") + if ( + length + and result.source_range is not None + and result.source_range.duration.value != length + ): + raise otio.exceptions.OTIOError( + "Wrong duration? {} should be {} in {}".format( + result.source_range.duration.value, + length, + result + ) + ) + + # Did we find a Track? + if isinstance(result, otio.schema.Track): + # Try to figure out the kind of Track it is + if hasattr(item, 'media_kind'): + media_kind = str(item.media_kind) + result.metadata["AAF"]["MediaKind"] = media_kind + if media_kind == "Picture": + result.kind = otio.schema.TrackKind.Video + elif media_kind in ("SoundMasterTrack", "Sound"): + result.kind = otio.schema.TrackKind.Audio + else: + # Timecode, Edgecode, others? + result.kind = None + + # Done! + return result + + +def _find_timecode_track_start(track): + # See if we can find a starting timecode in here... + aaf_metadata = track.metadata.get("AAF", {}) + + # Is this a Timecode track? + if aaf_metadata.get("MediaKind") == "Timecode": + edit_rate = aaf_metadata.get("EditRate", "0") + fps = aaf_metadata.get("Segment", {}).get("FPS", 0) + start = aaf_metadata.get("Segment", {}).get("Start", "0") + + # Often times there are several timecode tracks, so + # we use a heuristic to only pay attention to Timecode + # tracks with a FPS that matches the edit rate. + if edit_rate == str(fps): + return otio.opentime.RationalTime( + value=int(start), + rate=float(edit_rate) + ) + + # We didn't find anything useful + return None + + +def _transcribe_linear_timewarp(item, parameters): + # this is a linear time warp + effect = otio.schema.LinearTimeWarp() + + offset_map = _get_parameter(item, 'PARAM_SPEED_OFFSET_MAP_U') + + # If we have a LinearInterp with just 2 control points, then + # we can compute the time_scalar. Note that the SpeedRatio is + # NOT correct in many AAFs - we aren't sure why, but luckily we + # can compute the correct value this way. + points = offset_map.get("PointList") + if len(points) > 2: + # This is something complicated... try the fancy version + return _transcribe_fancy_timewarp(item, parameters) + elif ( + len(points) == 2 + and float(points[0].time) == 0 + and float(points[0].value) == 0 + ): + # With just two points, we can compute the slope + effect.time_scalar = float(points[1].value) / float(points[1].time) + else: + # Fall back to the SpeedRatio if we didn't understand the points + ratio = parameters.get("SpeedRatio") + if ratio == str(item.length): + # If the SpeedRatio == the length, this is a freeze frame + effect.time_scalar = 0 + elif '/' in ratio: + numerator, denominator = map(float, ratio.split('/')) + # OTIO time_scalar is 1/x from AAF's SpeedRatio + effect.time_scalar = denominator / numerator + else: + effect.time_scalar = 1.0 / float(ratio) + + # Is this is a freeze frame? + if effect.time_scalar == 0: + # Note: we might end up here if any of the code paths above + # produced a 0 time_scalar. + # Use the FreezeFrame class instead of LinearTimeWarp + effect = otio.schema.FreezeFrame() + + return effect + + +def _transcribe_fancy_timewarp(item, parameters): + + # For now, this is an unsupported time effect... + effect = otio.schema.TimeEffect() + effect.effect_name = None # Unsupported + effect.name = item.get("Name") + + return effect + + # TODO: Here is some sample code that pulls out the full + # details of a non-linear speed map. + + # speed_map = item.parameter['PARAM_SPEED_MAP_U'] + # offset_map = item.parameter['PARAM_SPEED_OFFSET_MAP_U'] + # Also? PARAM_OFFSET_MAP_U (without the word "SPEED" in it?) + # print(speed_map['PointList'].value) + # print(speed_map.count()) + # print(speed_map.interpolation_def().name) + # + # for p in speed_map.points(): + # print(" ", float(p.time), float(p.value), p.edit_hint) + # for prop in p.point_properties(): + # print(" ", prop.name, prop.value, float(prop.value)) + # + # print(offset_map.interpolation_def().name) + # for p in offset_map.points(): + # edit_hint = p.edit_hint + # time = p.time + # value = p.value + # + # pass + # # print " ", float(p.time), float(p.value) + # + # for i in range(100): + # float(offset_map.value_at("%i/100" % i)) + # + # # Test file PARAM_SPEED_MAP_U is AvidBezierInterpolator + # # currently no implement for value_at + # try: + # speed_map.value_at(.25) + # except NotImplementedError: + # pass + # else: + # raise + + +def _transcribe_operation_group(item, parents, metadata, editRate, masterMobs): + result = otio.schema.Stack() + + operation = metadata.get("Operation", {}) + parameters = metadata.get("Parameters", {}) + result.name = operation.get("Name") + + # Trust the length that is specified in the AAF + length = metadata.get("Length") + result.source_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(0, editRate), + otio.opentime.RationalTime(length, editRate) + ) + + # Look for speed effects... + effect = None + if operation.get("IsTimeWarp"): + if operation.get("Name") == "Motion Control": + + offset_map = _get_parameter(item, 'PARAM_SPEED_OFFSET_MAP_U') + # TODO: We should also check the PARAM_OFFSET_MAP_U which has + # an interpolation_def().name as well. + if offset_map is not None: + interpolation = offset_map.interpolation.name + else: + interpolation = None + + if interpolation == "LinearInterp": + effect = _transcribe_linear_timewarp(item, parameters) + else: + effect = _transcribe_fancy_timewarp(item, parameters) + + else: + # Unsupported time effect + effect = otio.schema.TimeEffect() + effect.effect_name = None # Unsupported + effect.name = operation.get("Name") + else: + # Unsupported effect + effect = otio.schema.Effect() + effect.effect_name = None # Unsupported + effect.name = operation.get("Name") + + if effect is not None: + result.effects.append(effect) + effect.metadata = { + "AAF": { + "Operation": operation, + "Parameters": parameters + } + } + + for segment in item.getvalue("InputSegments"): + child = _transcribe(segment, parents + [item], editRate, masterMobs) + if child: + _add_child(result, child, segment) + + return result + + +def _fix_transitions(thing): + if isinstance(thing, otio.schema.Timeline): + _fix_transitions(thing.tracks) + elif ( + isinstance(thing, otio.core.Composition) + or isinstance(thing, otio.schema.SerializableCollection) + ): + if isinstance(thing, otio.schema.Track): + for c, child in enumerate(thing): + + # Don't touch the Transitions themselves, + # only the Clips & Gaps next to them. + if not isinstance(child, otio.core.Item): + continue + + # Was the item before us a Transition? + if c > 0 and isinstance( + thing[c - 1], + otio.schema.Transition + ): + pre_trans = thing[c - 1] + + if child.source_range is None: + child.source_range = child.trimmed_range() + csr = child.source_range + child.source_range = otio.opentime.TimeRange( + start_time=csr.start_time + pre_trans.in_offset, + duration=csr.duration - pre_trans.in_offset + ) + + # Is the item after us a Transition? + if c < len(thing) - 1 and isinstance( + thing[c + 1], + otio.schema.Transition + ): + post_trans = thing[c + 1] + + if child.source_range is None: + child.source_range = child.trimmed_range() + csr = child.source_range + child.source_range = otio.opentime.TimeRange( + start_time=csr.start_time, + duration=csr.duration - post_trans.out_offset + ) + + for child in thing: + _fix_transitions(child) + + +def _simplify(thing): + if isinstance(thing, otio.schema.SerializableCollection): + if len(thing) == 1: + return _simplify(thing[0]) + else: + for c, child in enumerate(thing): + thing[c] = _simplify(child) + return thing + + elif isinstance(thing, otio.schema.Timeline): + result = _simplify(thing.tracks) + + # Only replace the Timeline's stack if the simplified result + # was also a Stack. Otherwise leave it (the contents will have + # been simplified in place). + if isinstance(result, otio.schema.Stack): + thing.tracks = result + + return thing + + elif isinstance(thing, otio.core.Composition): + # simplify our children + for c, child in enumerate(thing): + thing[c] = _simplify(child) + + # remove empty children of Stacks + if isinstance(thing, otio.schema.Stack): + for c in reversed(range(len(thing))): + child = thing[c] + if not _contains_something_valuable(child): + # TODO: We're discarding metadata... should we retain it? + del thing[c] + + # Look for Stacks within Stacks + c = len(thing) - 1 + while c >= 0: + child = thing[c] + # Is my child a Stack also? (with no effects) + if ( + not _has_effects(child) + and + ( + isinstance(child, otio.schema.Stack) + or ( + isinstance(child, otio.schema.Track) + and len(child) == 1 + and isinstance(child[0], otio.schema.Stack) + and child[0] + and isinstance(child[0][0], otio.schema.Track) + ) + ) + ): + if isinstance(child, otio.schema.Track): + child = child[0] + + # Pull the child's children into the parent + num = len(child) + children_of_child = child[:] + # clear out the ownership of 'child' + del child[:] + thing[c:c + 1] = children_of_child + + # TODO: We may be discarding metadata, should we merge it? + # TODO: Do we need to offset the markers in time? + thing.markers.extend(child.markers) + # Note: we don't merge effects, because we already made + # sure the child had no effects in the if statement above. + + c = c + num + c = c - 1 + + # skip redundant containers + if _is_redundant_container(thing): + # TODO: We may be discarding metadata here, should we merge it? + result = thing[0].deepcopy() + # TODO: Do we need to offset the markers in time? + result.markers.extend(thing.markers) + # TODO: The order of the effects is probably important... + # should they be added to the end or the front? + # Intuitively it seems like the child's effects should come before + # the parent's effects. This will need to be solidified when we + # add more effects support. + result.effects.extend(thing.effects) + # Keep the parent's length, if it has one + if thing.source_range: + # make sure it has a source_range first + if not result.source_range: + try: + result.source_range = result.trimmed_range() + except otio.exceptions.CannotComputeAvailableRangeError: + result.source_range = copy.copy(thing.source_range) + # modify the duration, but leave the start_time as is + result.source_range = otio.opentime.TimeRange( + result.source_range.start_time, + thing.source_range.duration + ) + return result + + # if thing is the top level stack, all of its children must be in tracks + if isinstance(thing, otio.schema.Stack) and thing.parent() is None: + children_needing_tracks = [] + for child in thing: + if isinstance(child, otio.schema.Track): + continue + children_needing_tracks.append(child) + + for child in children_needing_tracks: + orig_index = thing.index(child) + del thing[orig_index] + new_track = otio.schema.Track() + new_track.append(child) + thing.insert(orig_index, new_track) + + return thing + + +def _has_effects(thing): + if isinstance(thing, otio.core.Item): + if len(thing.effects) > 0: + return True + + +def _is_redundant_container(thing): + + is_composition = isinstance(thing, otio.core.Composition) + if not is_composition: + return False + + has_one_child = len(thing) == 1 + if not has_one_child: + return False + + am_top_level_track = ( + type(thing) is otio.schema.Track + and type(thing.parent()) is otio.schema.Stack + and thing.parent().parent() is None + ) + + return ( + not am_top_level_track + # am a top level track but my only child is a track + or ( + type(thing) is otio.schema.Track + and type(thing[0]) is otio.schema.Track + ) + ) + + +def _contains_something_valuable(thing): + if isinstance(thing, otio.core.Item): + if len(thing.effects) > 0 or len(thing.markers) > 0: + return True + + if isinstance(thing, otio.core.Composition): + + if len(thing) == 0: + # NOT valuable because it is empty + return False + + for child in thing: + if _contains_something_valuable(child): + # valuable because this child is valuable + return True + + # none of the children were valuable, so thing is NOT valuable + return False + + if isinstance(thing, otio.schema.Gap): + # TODO: Are there other valuable things we should look for on a Gap? + return False + + # anything else is presumed to be valuable + return True + + +def read_from_file(filepath, simplify=True): + + with aaf2.open(filepath) as aaf_file: + + storage = aaf_file.content + + # Note: We're skipping: f.header + # Is there something valuable in there? + + __names.clear() + masterMobs = {} + + result = _transcribe(storage, parents=list(), editRate=None, masterMobs=masterMobs) + top = storage.toplevel() + if top: + # re-transcribe just the top-level mobs + # but use all the master mobs we found in the 1st pass + __names.clear() # reset the names back to 0 + result = _transcribe(top, parents=list(), editRate=None, masterMobs=masterMobs) + + # AAF is typically more deeply nested than OTIO. + # Lets try to simplify the structure by collapsing or removing + # unnecessary stuff. + if simplify: + result = _simplify(result) + + # OTIO represents transitions a bit different than AAF, so + # we need to iterate over them and modify the items on either side. + # Note that we do this *after* simplifying, since the structure + # may change during simplification. + _fix_transitions(result) + + return result + + +def write_to_file(input_otio, filepath, **kwargs): + with aaf2.open(filepath, "w") as f: + + timeline = aaf_writer._stackify_nested_groups(input_otio) + + aaf_writer.validate_metadata(timeline) + + otio2aaf = aaf_writer.AAFFileTranscriber(timeline, f, **kwargs) + + if not isinstance(timeline, otio.schema.Timeline): + raise otio.exceptions.NotSupportedError( + "Currently only supporting top level Timeline") + + for otio_track in timeline.tracks: + # Ensure track must have clip to get the edit_rate + if len(otio_track) == 0: + continue + + transcriber = otio2aaf.track_transcriber(otio_track) + + for otio_child in otio_track: + result = transcriber.transcribe(otio_child) + if result: + transcriber.sequence.components.append(result) diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ale.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ale.py new file mode 100644 index 0000000000..150ed6d93d --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ale.py @@ -0,0 +1,318 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO Avid Log Exchange (ALE) Adapter""" +import re +import opentimelineio as otio + +DEFAULT_VIDEO_FORMAT = '1080' + + +def AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(width, height): + """Utility function to map a width and height to an Avid Project Format""" + + format_map = { + '1080': "1080", + '720': "720", + '576': "PAL", + '486': "NTSC", + } + mapped = format_map.get(str(height), "CUSTOM") + # check for the 2K DCI 1080 format + if mapped == '1080' and width > 1920: + mapped = "CUSTOM" + return mapped + + +class ALEParseError(otio.exceptions.OTIOError): + pass + + +def _parse_data_line(line, columns, fps): + row = line.split("\t") + + if len(row) < len(columns): + # Fill in blanks for any missing fields in this row + row.extend([""] * (len(columns) - len(row))) + + if len(row) > len(columns): + raise ALEParseError("Too many values on row: " + line) + + try: + + # Gather all the columns into a dictionary + # For expected columns, like Name, Start, etc. we will pop (remove) + # those from metadata, leaving the rest alone. + metadata = dict(zip(columns, row)) + + clip = otio.schema.Clip() + clip.name = metadata.pop("Name", None) + + # When looking for Start, Duration and End, they might be missing + # or blank. Treat None and "" as the same via: get(k,"")!="" + # To have a valid source range, you need Start and either Duration + # or End. If all three are provided, we check to make sure they match. + if metadata.get("Start", "") != "": + value = metadata.pop("Start") + try: + start = otio.opentime.from_timecode(value, fps) + except (ValueError, TypeError): + raise ALEParseError("Invalid Start timecode: {}".format(value)) + duration = None + end = None + if metadata.get("Duration", "") != "": + value = metadata.pop("Duration") + try: + duration = otio.opentime.from_timecode(value, fps) + except (ValueError, TypeError): + raise ALEParseError("Invalid Duration timecode: {}".format( + value + )) + if metadata.get("End", "") != "": + value = metadata.pop("End") + try: + end = otio.opentime.from_timecode(value, fps) + except (ValueError, TypeError): + raise ALEParseError("Invalid End timecode: {}".format( + value + )) + if duration is None: + duration = end - start + if end is None: + end = start + duration + if end != start + duration: + raise ALEParseError( + "Inconsistent Start, End, Duration: " + line + ) + clip.source_range = otio.opentime.TimeRange( + start, + duration + ) + + if metadata.get("Source File"): + source = metadata.pop("Source File") + clip.media_reference = otio.schema.ExternalReference( + target_url=source + ) + + # We've pulled out the key/value pairs that we treat specially. + # Put the remaining key/values into clip.metadata["ALE"] + clip.metadata["ALE"] = metadata + + return clip + except Exception as ex: + raise ALEParseError("Error parsing line: {}\n{}".format( + line, repr(ex) + )) + + +def _video_format_from_metadata(clips): + # Look for clips with Image Size metadata set + max_height = 0 + max_width = 0 + for clip in clips: + fields = clip.metadata.get("ALE", {}) + res = fields.get("Image Size", "") + m = re.search(r'([0-9]{1,})\s*[xX]\s*([0-9]{1,})', res) + if m and len(m.groups()) >= 2: + width = int(m.group(1)) + height = int(m.group(2)) + if height > max_height: + max_height = height + if width > max_width: + max_width = width + + # We don't have any image size information, use the defaut + if max_height == 0: + return DEFAULT_VIDEO_FORMAT + else: + return AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(max_width, max_height) + + +def read_from_string(input_str, fps=24): + + collection = otio.schema.SerializableCollection() + header = {} + columns = [] + + def nextline(lines): + return lines.pop(0) + + lines = input_str.splitlines() + while len(lines): + line = nextline(lines) + + # skip blank lines + if line.strip() == "": + continue + + if line.strip() == "Heading": + while len(lines): + line = nextline(lines) + + if line.strip() == "": + break + + if "\t" not in line: + raise ALEParseError("Invalid Heading line: " + line) + + segments = line.split("\t") + while len(segments) >= 2: + key, val = segments.pop(0), segments.pop(0) + header[key] = val + if len(segments) != 0: + raise ALEParseError("Invalid Heading line: " + line) + + if "FPS" in header: + fps = float(header["FPS"]) + + if line.strip() == "Column": + if len(lines) == 0: + raise ALEParseError("Unexpected end of file after: " + line) + + line = nextline(lines) + columns = line.split("\t") + + if line.strip() == "Data": + while len(lines): + line = nextline(lines) + + if line.strip() == "": + continue + + clip = _parse_data_line(line, columns, fps) + + collection.append(clip) + + collection.metadata["ALE"] = { + "header": header, + "columns": columns + } + + return collection + + +def write_to_string(input_otio, columns=None, fps=None, video_format=None): + + # Get all the clips we're going to export + clips = list(input_otio.each_clip()) + + result = "" + + result += "Heading\n" + header = dict(input_otio.metadata.get("ALE", {}).get("header", {})) + + # Force this, since we've hard coded tab delimiters + header["FIELD_DELIM"] = "TABS" + + if fps is None: + # If we weren't given a FPS, is there one in the header metadata? + if "FPS" in header: + fps = float(header["FPS"]) + else: + # Would it be better to infer this by inspecting the input clips? + fps = 24 + header["FPS"] = str(fps) + else: + # Put the value we were given into the header + header["FPS"] = str(fps) + + # Check if we have been supplied a VIDEO_FORMAT, if not lets set one + if video_format is None: + # Do we already have it in the header? If so, lets leave that as is + if "VIDEO_FORMAT" not in header: + header["VIDEO_FORMAT"] = _video_format_from_metadata(clips) + else: + header["VIDEO_FORMAT"] = str(video_format) + + headers = list(header.items()) + headers.sort() # make the output predictable + for key, val in headers: + result += "{}\t{}\n".format(key, val) + + # If the caller passed in a list of columns, use that, otherwise + # we need to discover the columns that should be output. + if columns is None: + # Is there a hint about the columns we want (and column ordering) + # at the top level? + columns = input_otio.metadata.get("ALE", {}).get("columns", []) + + # Scan all the clips for any extra columns + for clip in clips: + fields = clip.metadata.get("ALE", {}) + for key in fields.keys(): + if key not in columns: + columns.append(key) + + # Always output these + for c in ["Duration", "End", "Start", "Name", "Source File"]: + if c not in columns: + columns.insert(0, c) + + result += "\nColumn\n{}\n".format("\t".join(columns)) + + result += "\nData\n" + + def val_for_column(column, clip): + if column == "Name": + return clip.name + elif column == "Source File": + if ( + clip.media_reference and + hasattr(clip.media_reference, 'target_url') and + clip.media_reference.target_url + ): + return clip.media_reference.target_url + else: + return "" + elif column == "Start": + if not clip.source_range: + return "" + return otio.opentime.to_timecode( + clip.source_range.start_time, fps + ) + elif column == "Duration": + if not clip.source_range: + return "" + return otio.opentime.to_timecode( + clip.source_range.duration, fps + ) + elif column == "End": + if not clip.source_range: + return "" + return otio.opentime.to_timecode( + clip.source_range.end_time_exclusive(), fps + ) + else: + return clip.metadata.get("ALE", {}).get(column) + + for clip in clips: + row = [] + for column in columns: + val = str(val_for_column(column, clip) or "") + val.replace("\t", " ") # don't allow tabs inside a value + row.append(val) + result += "\t".join(row) + "\n" + + return result diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/burnins.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/burnins.py new file mode 100644 index 0000000000..93741bbb14 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/burnins.py @@ -0,0 +1,93 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# +"""FFMPEG Burnins Adapter""" +import os +import sys + + +def build_burnins(input_otio): + """ + Generates the burnin objects for each clip within the otio container + + :param input_otio: OTIO container + :rtype: [ffmpeg_burnins.Burnins(), ...] + """ + + if os.path.dirname(__file__) not in sys.path: + sys.path.append(os.path.dirname(__file__)) + + import ffmpeg_burnins + key = 'burnins' + + burnins = [] + for clip in input_otio.each_clip(): + + # per clip burnin data + burnin_data = clip.media_reference.metadata.get(key) + if not burnin_data: + # otherwise default to global burnin + burnin_data = input_otio.metadata.get(key) + + if not burnin_data: + continue + + media = clip.media_reference.target_url + if media.startswith('file://'): + media = media[7:] + streams = burnin_data.get('streams') + burnins.append(ffmpeg_burnins.Burnins(media, + streams=streams)) + burnins[-1].otio_media = media + burnins[-1].otio_overwrite = burnin_data.get('overwrite') + burnins[-1].otio_args = burnin_data.get('args') + + for burnin in burnin_data.get('burnins', []): + align = burnin.pop('align') + function = burnin.pop('function') + if function == 'text': + text = burnin.pop('text') + options = ffmpeg_burnins.TextOptions() + options.update(burnin) + burnins[-1].add_text(text, align, options=options) + elif function == 'frame_number': + options = ffmpeg_burnins.FrameNumberOptions() + options.update(burnin) + burnins[-1].add_frame_numbers(align, options=options) + elif function == 'timecode': + options = ffmpeg_burnins.TimeCodeOptions() + options.update(burnin) + burnins[-1].add_timecode(align, options=options) + else: + raise RuntimeError("Unknown function '%s'" % function) + + return burnins + + +def write_to_file(input_otio, filepath): + """required OTIO function hook""" + + for burnin in build_burnins(input_otio): + burnin.render(os.path.join(filepath, burnin.otio_media), + args=burnin.otio_args, + overwrite=burnin.otio_overwrite) diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/contrib_adapters.plugin_manifest.json b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/contrib_adapters.plugin_manifest.json new file mode 100644 index 0000000000..ceaf0a3067 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/contrib_adapters.plugin_manifest.json @@ -0,0 +1,61 @@ +{ + "OTIO_SCHEMA" : "PluginManifest.1", + "adapters": [ + { + "OTIO_SCHEMA": "Adapter.1", + "name": "fcpx_xml", + "execution_scope": "in process", + "filepath": "fcpx_xml.py", + "suffixes": ["fcpxml"] + }, + { + "OTIO_SCHEMA": "Adapter.1", + "name": "hls_playlist", + "execution_scope": "in process", + "filepath": "hls_playlist.py", + "suffixes": ["m3u8"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "rv_session", + "execution_scope" : "in process", + "filepath" : "rv.py", + "suffixes" : ["rv"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "maya_sequencer", + "execution_scope" : "in process", + "filepath" : "maya_sequencer.py", + "suffixes" : ["ma","mb"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "ale", + "execution_scope" : "in process", + "filepath" : "ale.py", + "suffixes" : ["ale"] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "burnins", + "execution_scope" : "in process", + "filepath" : "burnins.py", + "suffixes" : [] + }, + { + "OTIO_SCHEMA" : "Adapter.1", + "name" : "AAF", + "execution_scope" : "in process", + "filepath" : "advanced_authoring_format.py", + "suffixes" : ["aaf"] + }, + { + "OTIO_SCHEMA": "Adapter.1", + "name": "xges", + "execution_scope": "in process", + "filepath": "xges.py", + "suffixes": ["xges"] + } + ] +} diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_maya_sequencer.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_maya_sequencer.py new file mode 100644 index 0000000000..45d77976cf --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_maya_sequencer.py @@ -0,0 +1,261 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +import os +import sys + +# deal with renaming of default library from python 2 / 3 +try: + import urlparse as urllib_parse +except ImportError: + import urllib.parse as urllib_parse + +# import maya and handle standalone mode +from maya import cmds + +try: + cmds.ls +except AttributeError: + from maya import standalone + standalone.initialize(name='python') + +import opentimelineio as otio + +# Mapping of Maya FPS Enum to rate. +FPS = { + 'game': 15, + 'film': 24, + 'pal': 25, + 'ntsc': 30, + 'show': 48, + 'palf': 50, + 'ntscf': 60 +} + + +def _url_to_path(url): + if url is None: + return None + + return urllib_parse.urlparse(url).path + + +def _video_url_for_shot(shot): + current_file = os.path.normpath(cmds.file(q=True, sn=True)) + return os.path.join( + os.path.dirname(current_file), + 'playblasts', + '{base_name}_{shot_name}.mov'.format( + base_name=os.path.basename(os.path.splitext(current_file)[0]), + shot_name=cmds.shot(shot, q=True, shotName=True) + ) + ) + + +def _match_existing_shot(item, existing_shots): + if existing_shots is None: + return None + + if item.media_reference.is_missing_reference: + return None + + url_path = _url_to_path(item.media_reference.target_url) + return next( + ( + shot for shot in existing_shots + if _video_url_for_shot(shot) == url_path + ), + None + ) + + +# ------------------------ +# building single track +# ------------------------ + +def _build_shot(item, track_no, track_range, existing_shot=None): + camera = None + if existing_shot is None: + camera = cmds.camera(name=item.name.split('.')[0] + '_cam')[0] + cmds.shot( + existing_shot or item.name.split('.')[0], + e=existing_shot is not None, + shotName=item.name, + track=track_no, + currentCamera=camera, + startTime=item.trimmed_range().start_time.value, + endTime=item.trimmed_range().end_time_inclusive().value, + sequenceStartTime=track_range.start_time.value, + sequenceEndTime=track_range.end_time_inclusive().value + ) + + +def _build_track(track, track_no, existing_shots=None): + for n, item in enumerate(track): + if not isinstance(item, otio.schema.Clip): + continue + + track_range = track.range_of_child_at_index(n) + if existing_shots is not None: + existing_shot = _match_existing_shot(item, existing_shots) + else: + existing_shot = None + + _build_shot(item, track_no, track_range, existing_shot) + + +def build_sequence(timeline, clean=False): + existing_shots = cmds.ls(type='shot') or [] + if clean: + cmds.delete(existing_shots) + existing_shots = [] + + tracks = [ + track for track in timeline.tracks + if track.kind == otio.schema.TrackKind.Video + ] + + for track_no, track in enumerate(reversed(tracks)): + _build_track(track, track_no, existing_shots=existing_shots) + + +def read_from_file(path, clean=True): + timeline = otio.adapters.read_from_file(path) + build_sequence(timeline, clean=clean) + + +# ----------------------- +# parsing single track +# ----------------------- + +def _get_gap(duration): + rate = FPS.get(cmds.currentUnit(q=True, time=True), 25) + gap_range = otio.opentime.TimeRange( + duration=otio.opentime.RationalTime(duration, rate) + ) + return otio.schema.Gap(source_range=gap_range) + + +def _read_shot(shot): + rate = FPS.get(cmds.currentUnit(q=True, time=True), 25) + start = int(cmds.shot(shot, q=True, startTime=True)) + end = int(cmds.shot(shot, q=True, endTime=True)) + 1 + + video_reference = otio.schema.ExternalReference( + target_url=_video_url_for_shot(shot), + available_range=otio.opentime.TimeRange( + otio.opentime.RationalTime(value=start, rate=rate), + otio.opentime.RationalTime(value=end - start, rate=rate) + ) + ) + + return otio.schema.Clip( + name=cmds.shot(shot, q=True, shotName=True), + media_reference=video_reference, + source_range=otio.opentime.TimeRange( + otio.opentime.RationalTime(value=start, rate=rate), + otio.opentime.RationalTime(value=end - start, rate=rate) + ) + ) + + +def _read_track(shots): + v = otio.schema.Track(kind=otio.schema.track.TrackKind.Video) + + last_clip_end = 0 + for shot in shots: + seq_start = int(cmds.shot(shot, q=True, sequenceStartTime=True)) + seq_end = int(cmds.shot(shot, q=True, sequenceEndTime=True)) + + # add gap if necessary + fill_time = seq_start - last_clip_end + last_clip_end = seq_end + 1 + if fill_time: + v.append(_get_gap(fill_time)) + + # add clip + v.append(_read_shot(shot)) + + return v + + +def read_sequence(): + rate = FPS.get(cmds.currentUnit(q=True, time=True), 25) + shots = cmds.ls(type='shot') or [] + per_track = {} + + for shot in shots: + track_no = cmds.shot(shot, q=True, track=True) + if track_no not in per_track: + per_track[track_no] = [] + per_track[track_no].append(shot) + + timeline = otio.schema.Timeline() + timeline.global_start_time = otio.opentime.RationalTime(0, rate) + + for track_no in reversed(sorted(per_track.keys())): + track_shots = per_track[track_no] + timeline.tracks.append(_read_track(track_shots)) + + return timeline + + +def write_to_file(path): + timeline = read_sequence() + otio.adapters.write_to_file(timeline, path) + + +def main(): + read_write_arg = sys.argv[1] + filepath = sys.argv[2] + + write = False + if read_write_arg == "write": + write = True + + if write: + # read the input OTIO off stdin + input_otio = otio.adapters.read_from_string( + sys.stdin.read(), + 'otio_json' + ) + build_sequence(input_otio, clean=True) + cmds.file(rename=filepath) + cmds.file(save=True, type="mayaAscii") + else: + cmds.file(filepath, o=True) + sys.stdout.write( + "\nOTIO_JSON_BEGIN\n" + + otio.adapters.write_to_string( + read_sequence(), + "otio_json" + ) + + "\nOTIO_JSON_END\n" + ) + + cmds.quit(force=True) + + +if __name__ == "__main__": + main() diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_rv.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_rv.py new file mode 100644 index 0000000000..f11295bb60 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/extern_rv.py @@ -0,0 +1,327 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""RV External Adapter component. + +Because the rv adapter requires being run from within the RV py-interp to take +advantage of modules inside of RV, this script gets shelled out to from the +RV OTIO adapter. + +Requires that you set the environment variables: + OTIO_RV_PYTHON_LIB - should point at the parent directory of rvSession + OTIO_RV_PYTHON_BIN - should point at py-interp from within rv +""" + +# python +import sys +import os + +# otio +import opentimelineio as otio + +# rv import +sys.path += [os.path.join(os.environ["OTIO_RV_PYTHON_LIB"], "rvSession")] +import rvSession # noqa + + +def main(): + """ entry point, should be called from the rv adapter in otio """ + + session_file = rvSession.Session() + + output_fname = sys.argv[1] + + # read the input OTIO off stdin + input_otio = otio.adapters.read_from_string(sys.stdin.read(), 'otio_json') + + result = write_otio(input_otio, session_file) + session_file.setViewNode(result) + session_file.write(output_fname) + + +# exception class @{ +class NoMappingForOtioTypeError(otio.exceptions.OTIOError): + pass +# @} + + +def write_otio(otio_obj, to_session, track_kind=None): + WRITE_TYPE_MAP = { + otio.schema.Timeline: _write_timeline, + otio.schema.Stack: _write_stack, + otio.schema.Track: _write_track, + otio.schema.Clip: _write_item, + otio.schema.Gap: _write_item, + otio.schema.Transition: _write_transition, + otio.schema.SerializableCollection: _write_collection, + } + + if type(otio_obj) in WRITE_TYPE_MAP: + return WRITE_TYPE_MAP[type(otio_obj)](otio_obj, to_session, track_kind) + + raise NoMappingForOtioTypeError( + str(type(otio_obj)) + " on object: {}".format(otio_obj) + ) + + +def _write_dissolve(pre_item, in_dissolve, post_item, to_session, track_kind=None): + rv_trx = to_session.newNode("CrossDissolve", str(in_dissolve.name)) + + rate = pre_item.trimmed_range().duration.rate + rv_trx.setProperty( + "CrossDissolve", + "", + "parameters", + "startFrame", + rvSession.gto.FLOAT, + 1.0 + ) + rv_trx.setProperty( + "CrossDissolve", + "", + "parameters", + "numFrames", + rvSession.gto.FLOAT, + int( + ( + in_dissolve.in_offset + + in_dissolve.out_offset + ).rescaled_to(rate).value + ) + ) + + rv_trx.setProperty( + "CrossDissolve", + "", + "output", + "fps", + rvSession.gto.FLOAT, + rate + ) + + pre_item_rv = write_otio(pre_item, to_session, track_kind) + rv_trx.addInput(pre_item_rv) + + post_item_rv = write_otio(post_item, to_session, track_kind) + + node_to_insert = post_item_rv + + if ( + hasattr(pre_item, "media_reference") + and pre_item.media_reference + and pre_item.media_reference.available_range + and hasattr(post_item, "media_reference") + and post_item.media_reference + and post_item.media_reference.available_range + and ( + post_item.media_reference.available_range.start_time.rate != + pre_item.media_reference.available_range.start_time.rate + ) + ): + # write a retime to make sure post_item is in the timebase of pre_item + rt_node = to_session.newNode("Retime", "transition_retime") + rt_node.setTargetFps( + pre_item.media_reference.available_range.start_time.rate + ) + + post_item_rv = write_otio(post_item, to_session, track_kind) + + rt_node.addInput(post_item_rv) + node_to_insert = rt_node + + rv_trx.addInput(node_to_insert) + + return rv_trx + + +def _write_transition( + pre_item, + in_trx, + post_item, + to_session, + track_kind=None +): + trx_map = { + otio.schema.TransitionTypes.SMPTE_Dissolve: _write_dissolve, + } + + if in_trx.transition_type not in trx_map: + return + + return trx_map[in_trx.transition_type]( + pre_item, + in_trx, + post_item, + to_session, + track_kind + ) + + +def _write_stack(in_stack, to_session, track_kind=None): + new_stack = to_session.newNode("Stack", str(in_stack.name) or "tracks") + + for seq in in_stack: + result = write_otio(seq, to_session, track_kind) + if result: + new_stack.addInput(result) + + return new_stack + + +def _write_track(in_seq, to_session, _=None): + new_seq = to_session.newNode("Sequence", str(in_seq.name) or "track") + + items_to_serialize = otio.algorithms.track_with_expanded_transitions( + in_seq + ) + + track_kind = in_seq.kind + + for thing in items_to_serialize: + if isinstance(thing, tuple): + result = _write_transition(*thing, to_session=to_session, + track_kind=track_kind) + elif thing.duration().value == 0: + continue + else: + result = write_otio(thing, to_session, track_kind) + + if result: + new_seq.addInput(result) + + return new_seq + + +def _write_timeline(tl, to_session, _=None): + result = write_otio(tl.tracks, to_session) + return result + + +def _write_collection(collection, to_session, track_kind=None): + results = [] + for item in collection: + result = write_otio(item, to_session, track_kind) + if result: + results.append(result) + + if results: + return results[0] + + +def _create_media_reference(item, src, track_kind=None): + if hasattr(item, "media_reference") and item.media_reference: + if isinstance(item.media_reference, otio.schema.ExternalReference): + media = [str(item.media_reference.target_url)] + + if track_kind == otio.schema.TrackKind.Audio: + # Create blank video media to accompany audio for valid source + blank = "{},start={},end={},fps={}.movieproc".format( + "blank", + item.available_range().start_time.value, + item.available_range().end_time_inclusive().value, + item.available_range().duration.rate + ) + # Inserting blank media here forces all content to only + # produce audio. We do it twice in case we look at this in + # stereo + media = [blank, blank] + media + + src.setMedia(media) + return True + + elif isinstance(item.media_reference, otio.schema.GeneratorReference): + if item.media_reference.generator_kind == "SMPTEBars": + kind = "smptebars" + src.setMedia( + [ + "{},start={},end={},fps={}.movieproc".format( + kind, + item.available_range().start_time.value, + item.available_range().end_time_inclusive().value, + item.available_range().duration.rate + ) + ] + ) + return True + + return False + + +def _write_item(it, to_session, track_kind=None): + src = to_session.newNode("Source", str(it.name) or "clip") + + src.setProperty( + "RVSourceGroup", + "source", + "attributes", + "otio_metadata", + rvSession.gto.STRING, str(it.metadata) + ) + + range_to_read = it.trimmed_range() + + if not range_to_read: + raise otio.exceptions.OTIOError( + "No valid range on clip: {0}.".format( + str(it) + ) + ) + + # because OTIO has no global concept of FPS, the rate of the duration is + # used as the rate for the range of the source. + # RationalTime.value_rescaled_to returns the time value of the object in + # time rate of the argument. + src.setCutIn( + range_to_read.start_time.value_rescaled_to( + range_to_read.duration + ) + ) + src.setCutOut( + range_to_read.end_time_inclusive().value_rescaled_to( + range_to_read.duration + ) + ) + src.setFPS(range_to_read.duration.rate) + + # if the media reference is missing + if not _create_media_reference(it, src, track_kind): + kind = "smptebars" + if isinstance(it, otio.schema.Gap): + kind = "blank" + src.setMedia( + [ + "{},start={},end={},fps={}.movieproc".format( + kind, + range_to_read.start_time.value, + range_to_read.end_time_inclusive().value, + range_to_read.duration.rate + ) + ] + ) + + return src + + +if __name__ == "__main__": + main() diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/fcpx_xml.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/fcpx_xml.py new file mode 100644 index 0000000000..e219b58a1a --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/fcpx_xml.py @@ -0,0 +1,1182 @@ +# +# Copyright 2018 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO Final Cut Pro X XML Adapter. """ +import os +import subprocess +from xml.etree import cElementTree +from xml.dom import minidom +from fractions import Fraction +from datetime import date + +try: + from urllib import unquote +except ImportError: + from urllib.parse import unquote + +import opentimelineio as otio + +META_NAMESPACE = "fcpx_xml" + +COMPOSABLE_ELEMENTS = ("video", "audio", "ref-clip", "asset-clip") + +FRAMERATE_FRAMEDURATION = {23.98: "1001/24000s", + 24: "25/600s", + 25: "1/25s", + 29.97: "1001/30000s", + 30: "100/3000s", + 50: "1/50s", + 59.94: "1001/60000s", + 60: "1/60s"} + + +def format_name(frame_rate, path): + """ + Helper to get the formatName used in FCP X XML format elements. This + uses ffprobe to get the frame size of the the clip at the provided path. + + Args: + frame_rate (int): The frame rate of the clip at the provided path + path (str): The path to the clip to probe + + Returns: + str: The format name. If empty, then ffprobe couldn't find the item + """ + + path = path.replace("file://", "") + path = unquote(path) + if not os.path.exists(path): + return "" + + try: + frame_size = subprocess.check_output( + [ + "ffprobe", + "-v", + "error", + "-select_streams", + "v:0", + "-show_entries", + "stream=height,width", + "-of", + "csv=s=x:p=0", + path + ] + ) + except (subprocess.CalledProcessError, OSError): + frame_size = "" + + if not frame_size: + return "" + + frame_size = frame_size.rstrip() + + if "1920" in frame_size: + frame_size = "1080" + + if frame_size.endswith("1280"): + frame_size = "720" + + return "FFVideoFormat{}p{}".format(frame_size, frame_rate) + + +def to_rational_time(rational_number, fps): + """ + This converts a rational number value to an otio RationalTime object + + Args: + rational_number (str): This is a rational number from an FCP X XML + fps (int): The frame rate to use for calculating the rational time + + Returns: + RationalTime: A RationalTime object + """ + + if rational_number == "0s" or rational_number is None: + frames = 0 + else: + parts = rational_number.split("/") + if len(parts) > 1: + frames = int( + float(parts[0]) / float(parts[1].replace("s", "")) * float(fps) + ) + else: + frames = int(float(parts[0].replace("s", "")) * float(fps)) + + return otio.opentime.RationalTime(frames, int(fps)) + + +def from_rational_time(rational_time): + """ + This converts a RationalTime object to a rational number as a string + + Args: + rational_time (RationalTime): a rational time object + + Returns: + str: A rational number as a string + """ + + if int(rational_time.value) == 0: + return "0s" + result = Fraction( + float(rational_time.value) / float(rational_time.rate) + ).limit_denominator() + if str(result.denominator) == "1": + return "{}s".format(result.numerator) + return "{}/{}s".format(result.numerator, result.denominator) + + +class FcpxOtio(object): + """ + This object is responsible for knowing how to convert an otio into an + FCP X XML + """ + + def __init__(self, otio_timeline): + self.otio_timeline = otio_timeline + self.fcpx_xml = cElementTree.Element("fcpxml", version="1.8") + self.resource_element = cElementTree.SubElement( + self.fcpx_xml, + "resources" + ) + if self.otio_timeline.schema_name() == "Timeline": + self.timelines = [self.otio_timeline] + else: + self.timelines = list( + self.otio_timeline.each_child( + descended_from_type=otio.schema.Timeline + ) + ) + + if len(self.timelines) > 1: + self.event_resource = cElementTree.SubElement( + self.fcpx_xml, + "event", + {"name": self._event_name()} + ) + else: + self.event_resource = self.fcpx_xml + + self.resource_count = 0 + + def to_xml(self): + """ + Convert an otio to an FCP X XML + + Returns: + str: FCPX XML content + """ + + for project in self.timelines: + top_sequence = self._stack_to_sequence(project.tracks) + + project_element = cElementTree.Element( + "project", + { + "name": project.name, + "uid": project.metadata.get("fcpx", {}).get("uid", "") + } + ) + project_element.append(top_sequence) + self.event_resource.append(project_element) + + if not self.timelines: + for clip in self._clips(): + if not clip.parent(): + self._add_asset(clip) + + for stack in self._stacks(): + ref_element = self._element_for_item( + stack, + None, + ref_only=True, + compound=True + ) + self.event_resource.append(ref_element) + child_parent_map = {c: p for p in self.fcpx_xml.iter() for c in p} + + for marker in [marker for marker in self.fcpx_xml.iter("marker")]: + parent = child_parent_map.get(marker) + marker_attribs = marker.attrib.copy() + parent.remove(marker) + cElementTree.SubElement( + parent, + "marker", + marker_attribs + ) + + xml = cElementTree.tostring( + self.fcpx_xml, + encoding="UTF-8", + method="xml" + ) + dom = minidom.parseString(xml) + pretty = dom.toprettyxml(indent=" ") + return pretty.replace( + '', + '\n\n' + ) + + def _stack_to_sequence(self, stack, compound_clip=False): + format_element = self._find_or_create_format_from(stack) + sequence_element = cElementTree.Element( + "sequence", + { + "duration": self._calculate_rational_number( + stack.duration().value, + stack.duration().rate + ), + "format": str(format_element.get("id")) + } + ) + spine = cElementTree.SubElement(sequence_element, "spine") + video_tracks = [ + t for t in stack + if t.kind == otio.schema.TrackKind.Video + ] + audio_tracks = [ + t for t in stack + if t.kind == otio.schema.TrackKind.Audio + ] + + for idx, track in enumerate(video_tracks): + self._track_for_spine(track, idx, spine, compound_clip) + + for idx, track in enumerate(audio_tracks): + lane_id = -(idx + 1) + self._track_for_spine(track, lane_id, spine, compound_clip) + return sequence_element + + def _track_for_spine(self, track, lane_id, spine, compound): + for child in self._lanable_items(track.each_child()): + if self._item_in_compound_clip(child) and not compound: + continue + child_element = self._element_for_item( + child, + lane_id, + compound=compound + ) + if not lane_id: + spine.append(child_element) + continue + if child.schema_name() == "Gap": + continue + + parent_element = self._find_parent_element( + spine, + track.trimmed_range_of_child(child).start_time, + self._find_or_create_format_from(track).get("id") + ) + offset = self._offset_based_on_parent( + child_element, + parent_element, + self._find_or_create_format_from(track).get("id") + ) + child_element.set( + "offset", + from_rational_time(offset) + ) + + parent_element.append(child_element) + return [] + + def _find_parent_element(self, spine, trimmed_range, format_id): + for item in spine.iter(): + if item.tag not in ("clip", "asset-clip", "gap", "ref-clip"): + continue + if item.get("lane") is not None: + continue + if item.tag == "gap" and item.find("./audio") is not None: + continue + offset = to_rational_time( + item.get("offset"), + self._frame_rate_from_element(item, format_id) + ) + duration = to_rational_time( + item.get("duration"), + self._frame_rate_from_element(item, format_id) + ) + total_time = offset + duration + if offset > trimmed_range: + continue + if total_time > trimmed_range: + return item + return None + + def _offset_based_on_parent(self, child, parent, default_format_id): + parent_offset = to_rational_time( + parent.get("offset"), + self._frame_rate_from_element(parent, default_format_id) + ) + child_offset = to_rational_time( + child.get("offset"), + self._frame_rate_from_element(child, default_format_id) + ) + + parent_start = to_rational_time( + parent.get("start"), + self._frame_rate_from_element(parent, default_format_id) + ) + return (child_offset - parent_offset) + parent_start + + def _frame_rate_from_element(self, element, default_format_id): + if element.tag == "gap": + format_id = default_format_id + + if element.tag == "ref-clip": + media_element = self._media_by_id(element.get("ref")) + asset = media_element.find("./sequence") + format_id = asset.get("format") + + if element.tag == "clip": + if element.find("./gap") is not None: + asset_id = element.find("./gap").find("./audio").get("ref") + else: + asset_id = element.find("./video").get("ref") + asset = self._asset_by_id(asset_id) + format_id = asset.get("format") + + if element.tag == "asset-clip": + asset = self._asset_by_id(element.get("ref")) + format_id = asset.get("format") + + format_element = self.resource_element.find( + "./format[@id='{}']".format(format_id) + ) + total, rate = format_element.get("frameDuration").split("/") + rate = rate.replace("s", "") + return int(float(rate) / float(total)) + + def _element_for_item(self, item, lane, ref_only=False, compound=False): + element = None + duration = self._calculate_rational_number( + item.duration().value, + item.duration().rate + ) + if item.schema_name() == "Clip": + asset_id = self._add_asset(item, compound_only=compound) + element = self._element_for_clip(item, asset_id, duration, lane) + + if item.schema_name() == "Gap": + element = self._element_for_gap(item, duration) + + if item.schema_name() == "Stack": + element = self._element_for_stack(item, duration, ref_only) + + if element is None: + return None + if lane: + element.set("lane", str(lane)) + for marker in item.markers: + marker_attribs = { + "start": from_rational_time(marker.marked_range.start_time), + "duration": from_rational_time(marker.marked_range.duration), + "value": marker.name + } + marker_element = cElementTree.Element( + "marker", + marker_attribs + ) + if marker.color == otio.schema.MarkerColor.RED: + marker_element.set("completed", "0") + if marker.color == otio.schema.MarkerColor.GREEN: + marker_element.set("completed", "1") + element.append(marker_element) + return element + + def _lanable_items(self, items): + return [ + item for item in items + if item.schema_name() in ["Gap", "Stack", "Clip"] + ] + + def _element_for_clip(self, item, asset_id, duration, lane): + element = cElementTree.Element( + "clip", + { + "name": item.name, + "offset": from_rational_time( + item.trimmed_range_in_parent().start_time + ), + "duration": duration + } + ) + start = from_rational_time(item.source_range.start_time) + if start != "0s": + element.set("start", str(start)) + if item.parent().kind == otio.schema.TrackKind.Video: + cElementTree.SubElement( + element, + "video", + { + "offset": "0s", + "ref": asset_id, + "duration": self._find_asset_duration(item) + } + ) + else: + gap_element = cElementTree.SubElement( + element, + "gap", + { + "name": "Gap", + "offset": "0s", + "duration": self._find_asset_duration(item) + } + ) + audio = cElementTree.SubElement( + gap_element, + "audio", + { + "offset": "0s", + "ref": asset_id, + "duration": self._find_asset_duration(item) + } + ) + if lane: + audio.set("lane", str(lane)) + return element + + def _element_for_gap(self, item, duration): + element = cElementTree.Element( + "gap", + { + "name": "Gap", + "duration": duration, + "offset": from_rational_time( + item.trimmed_range_in_parent().start_time + ), + "start": "3600s" + } + ) + return element + + def _element_for_stack(self, item, duration, ref_only): + media_element = self._add_compound_clip(item) + asset_id = media_element.get("id") + element = cElementTree.Element( + "ref-clip", + { + "name": item.name, + "duration": duration, + "ref": str(asset_id) + } + ) + if not ref_only: + element.set( + "offset", + from_rational_time( + item.trimmed_range_in_parent().start_time + ) + ) + element.set( + "start", + from_rational_time(item.source_range.start_time) + ) + if item.parent() and item.parent().kind == otio.schema.TrackKind.Audio: + element.set("srcEnable", "audio") + return element + + def _find_asset_duration(self, item): + if (item.media_reference and + not item.media_reference.is_missing_reference): + return self._calculate_rational_number( + item.media_reference.available_range.duration.value, + item.media_reference.available_range.duration.rate + ) + return self._calculate_rational_number( + item.duration().value, + item.duration().rate + ) + + def _find_asset_start(self, item): + if (item.media_reference and + not item.media_reference.is_missing_reference): + return self._calculate_rational_number( + item.media_reference.available_range.start_time.value, + item.media_reference.available_range.start_time.rate + ) + return self._calculate_rational_number( + item.source_range.start_time.value, + item.source_range.start_time.rate + ) + + def _clip_format_name(self, clip): + if clip.schema_name() in ("Stack", "Track"): + return "" + if not clip.media_reference: + return "" + + if clip.media_reference.is_missing_reference: + return "" + + return format_name( + clip.duration().rate, + clip.media_reference.target_url + ) + + def _find_or_create_format_from(self, clip): + frame_duration = self._framerate_to_frame_duration( + clip.duration().rate + ) + format_element = self._format_by_frame_rate(clip.duration().rate) + if format_element is None: + format_element = cElementTree.SubElement( + self.resource_element, + "format", + { + "id": self._resource_id_generator(), + "frameDuration": frame_duration, + "name": self._clip_format_name(clip) + } + ) + if format_element.get("name", "") == "": + format_element.set("name", self._clip_format_name(clip)) + return format_element + + def _add_asset(self, clip, compound_only=False): + format_element = self._find_or_create_format_from(clip) + asset = self._create_asset_element(clip, format_element) + + if not compound_only and not self._asset_clip_by_name(clip.name): + self._create_asset_clip_element( + clip, + format_element, + asset.get("id") + ) + + if not clip.parent(): + asset.set("hasAudio", "1") + asset.set("hasVideo", "1") + return asset.get("id") + if clip.parent().kind == otio.schema.TrackKind.Audio: + asset.set("hasAudio", "1") + if clip.parent().kind == otio.schema.TrackKind.Video: + asset.set("hasVideo", "1") + return asset.get("id") + + def _create_asset_clip_element(self, clip, format_element, resource_id): + duration = self._find_asset_duration(clip) + a_clip = cElementTree.SubElement( + self.event_resource, + "asset-clip", + { + "name": clip.name, + "format": format_element.get("id"), + "ref": resource_id, + "duration": duration + } + ) + if clip.media_reference and not clip.media_reference.is_missing_reference: + fcpx_metadata = clip.media_reference.metadata.get("fcpx", {}) + note_element = self._create_note_element( + fcpx_metadata.get("note", None) + ) + keyword_elements = self._create_keyword_elements( + fcpx_metadata.get("keywords", []) + ) + metadata_element = self._create_metadata_elements( + fcpx_metadata.get("metadata", None) + ) + + if note_element is not None: + a_clip.append(note_element) + if keyword_elements: + for keyword_element in keyword_elements: + a_clip.append(keyword_element) + if metadata_element is not None: + a_clip.append(metadata_element) + + def _create_asset_element(self, clip, format_element): + target_url = self._target_url_from_clip(clip) + asset = self._asset_by_path(target_url) + if asset is not None: + return asset + + asset = cElementTree.SubElement( + self.resource_element, + "asset", + { + "name": clip.name, + "src": target_url, + "format": format_element.get("id"), + "id": self._resource_id_generator(), + "duration": self._find_asset_duration(clip), + "start": self._find_asset_start(clip), + "hasAudio": "0", + "hasVideo": "0" + } + ) + return asset + + def _add_compound_clip(self, item): + media_element = self._media_by_name(item.name) + if media_element is not None: + return media_element + resource_id = self._resource_id_generator() + media_element = cElementTree.SubElement( + self.resource_element, + "media", + { + "name": self._compound_clip_name(item, resource_id), + "id": resource_id + } + ) + if item.metadata.get("fcpx", {}).get("uid", False): + media_element.set("uid", item.metadata.get("fcpx", {}).get("uid")) + media_element.append(self._stack_to_sequence(item, compound_clip=True)) + return media_element + + def _stacks(self): + return self.otio_timeline.each_child( + descended_from_type=otio.schema.Stack + ) + + def _clips(self): + return self.otio_timeline.each_child( + descended_from_type=otio.schema.Clip + ) + + def _resource_id_generator(self): + self.resource_count += 1 + return "r{}".format(self.resource_count) + + def _event_name(self): + if self.otio_timeline.name: + return self.otio_timeline.name + return date.strftime(date.today(), "%m-%e-%y") + + def _asset_by_path(self, path): + return self.resource_element.find("./asset[@src='{}']".format(path)) + + def _asset_by_id(self, asset_id): + return self.resource_element.find("./asset[@id='{}']".format(asset_id)) + + def _media_by_name(self, name): + return self.resource_element.find("./media[@name='{}']".format(name)) + + def _media_by_id(self, media_id): + return self.resource_element.find("./media[@id='{}']".format(media_id)) + + def _format_by_frame_rate(self, frame_rate): + frame_duration = self._framerate_to_frame_duration(frame_rate) + return self.resource_element.find( + "./format[@frameDuration='{}']".format(frame_duration) + ) + + def _asset_clip_by_name(self, name): + return self.event_resource.find( + "./asset-clip[@name='{}']".format(name) + ) + + # -------------------- + # static methods + # -------------------- + + @staticmethod + def _framerate_to_frame_duration(framerate): + frame_duration = FRAMERATE_FRAMEDURATION.get(int(framerate), "") + if not frame_duration: + frame_duration = FRAMERATE_FRAMEDURATION.get(float(framerate), "") + return frame_duration + + @staticmethod + def _target_url_from_clip(clip): + if (clip.media_reference and + not clip.media_reference.is_missing_reference): + return clip.media_reference.target_url + return "file:///tmp/{}".format(clip.name) + + @staticmethod + def _calculate_rational_number(duration, rate): + if int(duration) == 0: + return "0s" + result = Fraction(float(duration) / float(rate)).limit_denominator() + return "{}/{}s".format(result.numerator, result.denominator) + + @staticmethod + def _compound_clip_name(compound_clip, resource_id): + if compound_clip.name: + return compound_clip.name + return "compound_clip_{}".format(resource_id) + + @staticmethod + def _item_in_compound_clip(item): + stack_count = 0 + parent = item.parent() + while parent is not None: + if parent.schema_name() == "Stack": + stack_count += 1 + parent = parent.parent() + return stack_count > 1 + + @staticmethod + def _create_metadata_elements(metadata): + if metadata is None: + return None + metadata_element = cElementTree.Element( + "metadata" + ) + for metadata_dict in metadata: + cElementTree.SubElement( + metadata_element, + "md", + { + "key": list(metadata_dict.keys())[0], + "value": list(metadata_dict.values())[0] + } + ) + return metadata_element + + @staticmethod + def _create_keyword_elements(keywords): + keyword_elements = [] + for keyword_dict in keywords: + keyword_elements.append( + cElementTree.Element( + "keyword", + keyword_dict + ) + ) + return keyword_elements + + @staticmethod + def _create_note_element(note): + if not note: + return None + note_element = cElementTree.Element( + "note" + ) + note_element.text = note + return note_element + + +class FcpxXml(object): + """ + This object is responsible for knowing how to convert an FCP X XML + otio into an otio timeline + """ + + def __init__(self, xml_string): + self.fcpx_xml = cElementTree.fromstring(xml_string) + self.child_parent_map = {c: p for p in self.fcpx_xml.iter() for c in p} + + def to_otio(self): + """ + Convert an FCP X XML to an otio + + Returns: + OpenTimeline: An OpenTimeline Timeline object + """ + + if self.fcpx_xml.find("./library") is not None: + return self._from_library() + if self.fcpx_xml.find("./event") is not None: + return self._from_event(self.fcpx_xml.find("./event")) + if self.fcpx_xml.find("./project") is not None: + return self._from_project(self.fcpx_xml.find("./project")) + if ((self.fcpx_xml.find("./asset-clip") is not None) or + (self.fcpx_xml.find("./ref-clip") is not None)): + return self._from_clips() + + def _from_library(self): + # We are just grabbing the first even in the project for now + return self._from_event(self.fcpx_xml.find("./library/event")) + + def _from_event(self, event_element): + container = otio.schema.SerializableCollection( + name=event_element.get("name") + ) + for project in event_element.findall("./project"): + container.append(self._from_project(project)) + return container + + def _from_project(self, project_element): + timeline = otio.schema.Timeline(name=project_element.get("name", "")) + timeline.tracks = self._squence_to_stack( + project_element.find("./sequence", {}) + ) + return timeline + + def _from_clips(self): + container = otio.schema.SerializableCollection() + if self.fcpx_xml.find("./asset-clip") is not None: + for asset_clip in self.fcpx_xml.findall("./asset-clip"): + container.append( + self._build_composable( + asset_clip, + asset_clip.get("format") + ) + ) + + if self.fcpx_xml.find("./ref-clip") is not None: + for ref_clip in self.fcpx_xml.findall("./ref-clip"): + container.append( + self._build_composable( + ref_clip, + "r1" + ) + ) + return container + + def _squence_to_stack(self, sequence_element, name="", source_range=None): + timeline_items = [] + lanes = [] + stack = otio.schema.Stack(name=name, source_range=source_range) + for element in sequence_element.iter(): + if element.tag not in COMPOSABLE_ELEMENTS: + continue + composable = self._build_composable( + element, + sequence_element.get("format") + ) + + offset, lane = self._offset_and_lane( + element, + sequence_element.get("format") + ) + + timeline_items.append( + { + "track": lane, + "offset": offset, + "composable": composable, + "audio_only": self._audio_only(element) + } + ) + + lanes.append(lane) + sorted_lanes = list(set(lanes)) + sorted_lanes.sort() + for lane in sorted_lanes: + sorted_items = self._sorted_items(lane, timeline_items) + track = otio.schema.Track( + name=lane, + kind=self._track_type(sorted_items) + ) + + for item in sorted_items: + frame_diff = ( + int(item["offset"].value) - track.duration().value + ) + if frame_diff > 0: + track.append( + self._create_gap( + 0, + frame_diff, + sequence_element.get("format") + ) + ) + track.append(item["composable"]) + stack.append(track) + return stack + + def _build_composable(self, element, default_format): + timing_clip = self._timing_clip(element) + source_range = self._time_range( + timing_clip, + self._format_id_for_clip(element, default_format) + ) + + if element.tag != "ref-clip": + otio_composable = otio.schema.Clip( + name=timing_clip.get("name"), + media_reference=self._reference_from_id( + element.get("ref"), + default_format + ), + source_range=source_range + ) + else: + media_element = self._compound_clip_by_id(element.get("ref")) + otio_composable = self._squence_to_stack( + media_element.find("./sequence"), + name=media_element.get("name"), + source_range=source_range + ) + + for marker in timing_clip.findall(".//marker"): + otio_composable.markers.append( + self._marker(marker, default_format) + ) + + return otio_composable + + def _marker(self, element, default_format): + if element.get("completed", None) and element.get("completed") == "1": + color = otio.schema.MarkerColor.GREEN + if element.get("completed", None) and element.get("completed") == "0": + color = otio.schema.MarkerColor.RED + if not element.get("completed", None): + color = otio.schema.MarkerColor.PURPLE + + otio_marker = otio.schema.Marker( + name=element.get("value", ""), + marked_range=self._time_range(element, default_format), + color=color + ) + return otio_marker + + def _audio_only(self, element): + if element.tag == "audio": + return True + if element.tag == "asset-clip": + asset = self._asset_by_id(element.get("ref", None)) + if asset and asset.get("hasVideo", "0") == "0": + return True + if element.tag == "ref-clip": + if element.get("srcEnable", "video") == "audio": + return True + return False + + def _create_gap(self, start_frame, number_of_frames, defualt_format): + fps = self._format_frame_rate(defualt_format) + source_range = otio.opentime.TimeRange( + start_time=otio.opentime.RationalTime(start_frame, fps), + duration=otio.opentime.RationalTime(number_of_frames, fps) + ) + return otio.schema.Gap(source_range=source_range) + + def _timing_clip(self, clip): + while clip.tag not in ("clip", "asset-clip", "ref-clip"): + clip = self.child_parent_map.get(clip) + return clip + + def _offset_and_lane(self, clip, default_format): + clip_format_id = self._format_id_for_clip(clip, default_format) + clip = self._timing_clip(clip) + parent = self.child_parent_map.get(clip) + + parent_format_id = self._format_id_for_clip(parent, default_format) + + if parent.tag == "spine" and parent.get("lane", None): + lane = parent.get("lane") + parent = self.child_parent_map.get(parent) + spine = True + else: + lane = clip.get("lane", "0") + spine = False + + clip_offset_frames = self._number_of_frames( + clip.get("offset"), + clip_format_id + ) + + if spine: + parent_start_frames = 0 + else: + parent_start_frames = self._number_of_frames( + parent.get("start", None), + parent_format_id + ) + + parent_offset_frames = self._number_of_frames( + parent.get("offset", None), + parent_format_id + ) + + clip_offset_frames = ( + (int(clip_offset_frames) - int(parent_start_frames)) + + int(parent_offset_frames) + ) + + offset = otio.opentime.RationalTime( + clip_offset_frames, + self._format_frame_rate(clip_format_id) + ) + + return offset, lane + + def _format_id_for_clip(self, clip, default_format): + if not clip.get("ref", None) or clip.tag == "gap": + return default_format + + resource = self._asset_by_id(clip.get("ref")) + + if resource is None: + resource = self._compound_clip_by_id( + clip.get("ref") + ).find("sequence") + + return resource.get("format", default_format) + + def _reference_from_id(self, asset_id, default_format): + asset = self._asset_by_id(asset_id) + if not asset.get("src", ""): + return otio.schema.MissingReference() + + available_range = otio.opentime.TimeRange( + start_time=to_rational_time( + asset.get("start"), + self._format_frame_rate( + asset.get("format", default_format) + ) + ), + duration=to_rational_time( + asset.get("duration"), + self._format_frame_rate( + asset.get("format", default_format) + ) + ) + ) + asset_clip = self._assetclip_by_ref(asset_id) + metadata = {} + if asset_clip: + metadata = self._create_metadta(asset_clip) + return otio.schema.ExternalReference( + target_url=asset.get("src"), + available_range=available_range, + metadata={"fcpx": metadata} + ) + + def _create_metadta(self, item): + metadata = {} + for element in item.iter(): + if element.tag == "md": + metadata.setdefault("metadata", []).append( + {element.attrib.get("key"): element.attrib.get("value")} + ) + # metadata.update( + # {element.attrib.get("key"): element.attrib.get("value")} + # ) + if element.tag == "note": + metadata.update({"note": element.text}) + if element.tag == "keyword": + metadata.setdefault("keywords", []).append(element.attrib) + return metadata + + # -------------------- + # time helpers + # -------------------- + def _format_frame_duration(self, format_id): + media_format = self._format_by_id(format_id) + total, rate = media_format.get("frameDuration").split("/") + rate = rate.replace("s", "") + return total, rate + + def _format_frame_rate(self, format_id): + fd_total, fd_rate = self._format_frame_duration(format_id) + return int(float(fd_rate) / float(fd_total)) + + def _number_of_frames(self, time_value, format_id): + if time_value == "0s" or time_value is None: + return 0 + fd_total, fd_rate = self._format_frame_duration(format_id) + time_value = time_value.split("/") + + if len(time_value) > 1: + time_value_a, time_value_b = time_value + return int( + (float(time_value_a) / float(time_value_b.replace("s", ""))) * + (float(fd_rate) / float(fd_total)) + ) + + return int( + int(time_value[0].replace("s", "")) * + (float(fd_rate) / float(fd_total)) + ) + + def _time_range(self, element, format_id): + return otio.opentime.TimeRange( + start_time=to_rational_time( + element.get("start", "0s"), + self._format_frame_rate(format_id) + ), + duration=to_rational_time( + element.get("duration"), + self._format_frame_rate(format_id) + ) + ) + # -------------------- + # search helpers + # -------------------- + + def _asset_by_id(self, asset_id): + return self.fcpx_xml.find( + "./resources/asset[@id='{}']".format(asset_id) + ) + + def _assetclip_by_ref(self, asset_id): + event = self.fcpx_xml.find("./event") + if event is None: + return self.fcpx_xml.find("./asset-clip[@ref='{}']".format(asset_id)) + else: + return event.find("./asset-clip[@ref='{}']".format(asset_id)) + + def _format_by_id(self, format_id): + return self.fcpx_xml.find( + "./resources/format[@id='{}']".format(format_id) + ) + + def _compound_clip_by_id(self, compound_id): + return self.fcpx_xml.find( + "./resources/media[@id='{}']".format(compound_id) + ) + + # -------------------- + # static methods + # -------------------- + @staticmethod + def _track_type(lane_items): + audio_only_items = [l for l in lane_items if l["audio_only"]] + if len(audio_only_items) == len(lane_items): + return otio.schema.TrackKind.Audio + return otio.schema.TrackKind.Video + + @staticmethod + def _sorted_items(lane, otio_objects): + lane_items = [item for item in otio_objects if item["track"] == lane] + return sorted(lane_items, key=lambda k: k["offset"]) + + +# -------------------- +# adapter requirements +# -------------------- +def read_from_string(input_str): + """ + Necessary read method for otio adapter + + Args: + input_str (str): An FCP X XML string + + Returns: + OpenTimeline: An OpenTimeline object + """ + + return FcpxXml(input_str).to_otio() + + +def write_to_string(input_otio): + """ + Necessary write method for otio adapter + + Args: + input_otio (OpenTimeline): An OpenTimeline object + + Returns: + str: The string contents of an FCP X XML + """ + + return FcpxOtio(input_otio).to_xml() diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ffmpeg_burnins.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ffmpeg_burnins.py new file mode 100644 index 0000000000..28f0b97f55 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/ffmpeg_burnins.py @@ -0,0 +1,424 @@ +# MIT License +# +# Copyright (c) 2017 Ed Caspersen +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# allcopies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +""" +This module provides an interface to allow users to easily +build out an FFMPEG command with all the correct filters +for applying text (with a background) to the rendered media. +""" +import os +import sys +import json +from subprocess import Popen, PIPE +from PIL import ImageFont + + +def _is_windows(): + """ + queries if the current operating system is Windows + + :rtype: bool + """ + return sys.platform.startswith('win') or \ + sys.platform.startswith('cygwin') + + +def _system_font(): + """ + attempts to determine a default system font + + :rtype: str + """ + if _is_windows(): + font_path = os.path.join(os.environ['WINDIR'], 'Fonts') + fonts = ('arial.ttf', 'calibri.ttf', 'times.ttf') + elif sys.platform.startswith('darwin'): + font_path = '/System/Library/Fonts' + fonts = ('Menlo.ttc',) + else: + # assuming linux + font_path = 'usr/share/fonts/msttcorefonts' + fonts = ('arial.ttf', 'times.ttf', 'couri.ttf') + + system_font = None + backup = None + for font in fonts: + font = os.path.join(font_path, font) + if os.path.exists(font): + system_font = font + break + else: + if os.path.exists(font_path): + for each in os.listdir(font_path): + ext = os.path.splitext(each)[-1] + if ext[1:].startswith('tt'): + system_font = os.path.join(font_path, each) + return system_font or backup + + +# Default valuues +FONT = _system_font() +FONT_SIZE = 16 +FONT_COLOR = 'white' +BG_COLOR = 'black' +BG_PADDING = 5 + +# FFMPEG command strings +FFMPEG = ('ffmpeg -loglevel panic -i %(input)s ' + '%(filters)s %(args)s%(output)s') +FFPROBE = ('ffprobe -v quiet -print_format json -show_format ' + '-show_streams %(source)s') +BOX = 'box=1:boxborderw=%(border)d:boxcolor=%(color)s@%(opacity).1f' +DRAWTEXT = ("drawtext=text='%(text)s':x=%(x)s:y=%(y)s:fontcolor=" + "%(color)s@%(opacity).1f:fontsize=%(size)d:fontfile='%(font)s'") +TIMECODE = ("drawtext=timecode='%(text)s':timecode_rate=%(fps).2f" + ":x=%(x)s:y=%(y)s:fontcolor=" + "%(color)s@%(opacity).1f:fontsize=%(size)d:fontfile='%(font)s'") + + +# Valid aligment parameters. +TOP_CENTERED = 'top_centered' +BOTTOM_CENTERED = 'bottom_centered' +TOP_LEFT = 'top_left' +BOTTOM_LEFT = 'bottom_left' +TOP_RIGHT = 'top_right' +BOTTOM_RIGHT = 'bottom_right' + + +class Options(dict): + """ + Base options class. + """ + _params = { + 'opacity': 1, + 'x_offset': 0, + 'y_offset': 0, + 'font': FONT, + 'font_size': FONT_SIZE, + 'bg_color': BG_COLOR, + 'bg_padding': BG_PADDING, + 'font_color': FONT_COLOR + } + + def __init__(self, **kwargs): + super(Options, self).__init__() + params = self._params.copy() + params.update(kwargs) + super(Options, self).update(**params) + + def __setitem__(self, key, value): + if key not in self._params: + raise KeyError("Not a valid option key '%s'" % key) + super(Options, self).update({key: value}) + + +class FrameNumberOptions(Options): + """ + :key int frame_offset: offset the frame numbers + :key float opacity: opacity value (0-1) + :key str expression: expression that would be used instead of text + :key bool x_offset: X position offset + (does not apply to centered alignments) + :key bool y_offset: Y position offset + :key str font: path to the font file + :key int font_size: size to render the font in + :key str bg_color: background color of the box + :key int bg_padding: padding between the font and box + :key str font_color: color to render + """ + + def __init__(self, **kwargs): + self._params.update({ + 'frame_offset': 0, + 'expression': None + }) + super(FrameNumberOptions, self).__init__(**kwargs) + + +class TextOptions(Options): + """ + :key float opacity: opacity value (0-1) + :key str expression: expression that would be used instead of text + :key bool x_offset: X position offset + (does not apply to centered alignments) + :key bool y_offset: Y position offset + :key str font: path to the font file + :key int font_size: size to render the font in + :key str bg_color: background color of the box + :key int bg_padding: padding between the font and box + :key str font_color: color to render + """ + + +class TimeCodeOptions(Options): + """ + :key int frame_offset: offset the frame numbers + :key float fps: frame rate to calculate the timecode by + :key float opacity: opacity value (0-1) + :key bool x_offset: X position offset + (does not apply to centered alignments) + :key bool y_offset: Y position offset + :key str font: path to the font file + :key int font_size: size to render the font in + :key str bg_color: background color of the box + :key int bg_padding: padding between the font and box + :key str font_color: color to render + """ + + def __init__(self, **kwargs): + self._params.update({ + 'frame_offset': 0, + 'fps': 24 + }) + super(TimeCodeOptions, self).__init__(**kwargs) + + +class Burnins(object): + """ + Class that provides convenience API for building filter + flags for the FFMPEG command. + """ + + def __init__(self, source, streams=None): + """ + :param str source: source media file + :param [] streams: ffprobe stream data if parsed as a pre-process + """ + self.source = source + self.filters = { + 'drawtext': [] + } + self._streams = streams or _streams(self.source) + + def __repr__(self): + return '' % os.path.basename(self.source) + + @property + def start_frame(self): + """ + :rtype: int + """ + start_time = float(self._video_stream['start_time']) + return round(start_time * self.frame_rate) + + @property + def end_frame(self): + """ + :rtype: int + """ + end_time = float(self._video_stream['duration']) + return round(end_time * self.frame_rate) + + @property + def frame_rate(self): + """ + :rtype: int + """ + data = self._video_stream + tokens = data['r_frame_rate'].split('/') + return int(tokens[0]) / int(tokens[1]) + + @property + def _video_stream(self): + video_stream = None + for each in self._streams: + if each.get('codec_type') == 'video': + video_stream = each + break + else: + raise RuntimeError("Failed to locate video stream " + "from '%s'" % self.source) + return video_stream + + @property + def resolution(self): + """ + :rtype: (int, int) + """ + data = self._video_stream + return data['width'], data['height'] + + @property + def filter_string(self): + """ + Generates the filter string that would be applied + to the `-vf` argument + + :rtype: str + """ + return ','.join(self.filters['drawtext']) + + def add_timecode(self, align, options=None): + """ + Convenience method to create the frame number expression. + + :param enum align: alignment, must use provided enum flags + :param dict options: recommended to use TimeCodeOptions + """ + options = options or TimeCodeOptions() + timecode = _frames_to_timecode(options['frame_offset'], + self.frame_rate) + options = options.copy() + if not options.get('fps'): + options['fps'] = self.frame_rate + self._add_burnin(timecode.replace(':', r'\:'), + align, + options, + TIMECODE) + + def add_frame_numbers(self, align, options=None): + """ + Convenience method to create the frame number expression. + + :param enum align: alignment, must use provided enum flags + :param dict options: recommended to use FrameNumberOptions + """ + options = options or FrameNumberOptions() + options['expression'] = r'%%{eif\:n+%d\:d}' % options['frame_offset'] + text = str(int(self.end_frame + options['frame_offset'])) + self._add_burnin(text, align, options, DRAWTEXT) + + def add_text(self, text, align, options=None): + """ + Adding static text to a filter. + + :param str text: text to apply to the drawtext + :param enum align: alignment, must use provided enum flags + :param dict options: recommended to use TextOptions + """ + options = options or TextOptions() + self._add_burnin(text, align, options, DRAWTEXT) + + def _add_burnin(self, text, align, options, draw): + """ + Generic method for building the filter flags. + + :param str text: text to apply to the drawtext + :param enum align: alignment, must use provided enum flags + :param dict options: + """ + resolution = self.resolution + data = { + 'text': options.get('expression') or text, + 'color': options['font_color'], + 'size': options['font_size'] + } + data.update(options) + data.update(_drawtext(align, resolution, text, options)) + if 'font' in data and _is_windows(): + data['font'] = data['font'].replace(os.sep, r'\\' + os.sep) + data['font'] = data['font'].replace(':', r'\:') + self.filters['drawtext'].append(draw % data) + + if options.get('bg_color') is not None: + box = BOX % { + 'border': options['bg_padding'], + 'color': options['bg_color'], + 'opacity': options['opacity'] + } + self.filters['drawtext'][-1] += ':%s' % box + + def command(self, output=None, args=None, overwrite=False): + """ + Generate the entire FFMPEG command. + + :param str output: output file + :param str args: additional FFMPEG arguments + :param bool overwrite: overwrite the output if it exists + :returns: completed command + :rtype: str + """ + output = output or '' + if overwrite: + output = '-y %s' % output + return (FFMPEG % { + 'input': self.source, + 'output': output, + 'args': '%s ' % args if args else '', + 'filters': '-vf "%s"' % self.filter_string + }).strip() + + def render(self, output, args=None, overwrite=False): + """ + Render the media to a specified destination. + + :param str output: output file + :param str args: additional FFMPEG arguments + :param bool overwrite: overwrite the output if it exists + """ + if not overwrite and os.path.exists(output): + raise RuntimeError("Destination '%s' exists, please " + "use overwrite" % output) + command = self.command(output=output, + args=args, + overwrite=overwrite) + proc = Popen(command, shell=True) + proc.communicate() + if proc.returncode != 0: + raise RuntimeError("Failed to render '%s': %s'" + % (output, command)) + if not os.path.exists(output): + raise RuntimeError("Failed to generate '%s'" % output) + + +def _streams(source): + """ + :param str source: source media file + :rtype: [{}, ...] + """ + command = FFPROBE % {'source': source} + proc = Popen(command, shell=True, stdout=PIPE) + out = proc.communicate()[0] + if proc.returncode != 0: + raise RuntimeError("Failed to run: %s" % command) + return json.loads(out)['streams'] + + +def _drawtext(align, resolution, text, options): + """ + :rtype: {'x': int, 'y': int} + """ + x_pos = '0' + if align in (TOP_CENTERED, BOTTOM_CENTERED): + x_pos = 'w/2-tw/2' + elif align in (TOP_RIGHT, BOTTOM_RIGHT): + ifont = ImageFont.truetype(options['font'], + options['font_size']) + box_size = ifont.getsize(text) + x_pos = resolution[0] - (box_size[0] + options['x_offset']) + elif align in (TOP_LEFT, BOTTOM_LEFT): + x_pos = options['x_offset'] + + if align in (TOP_CENTERED, + TOP_RIGHT, + TOP_LEFT): + y_pos = '%d' % options['y_offset'] + else: + y_pos = 'h-text_h-%d' % (options['y_offset']) + return {'x': x_pos, 'y': y_pos} + + +def _frames_to_timecode(frames, framerate): + return '{0:02d}:{1:02d}:{2:02d}:{3:02d}'.format( + int(frames / (3600 * framerate)), + int(frames / (60 * framerate) % 60), + int(frames / framerate % 60), + int(frames % framerate)) diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/hls_playlist.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/hls_playlist.py new file mode 100644 index 0000000000..e0e3f8f872 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/hls_playlist.py @@ -0,0 +1,1781 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""HLS Playlist OpenTimelineIO adapter + +This adapter supports authoring of HLS playlists within OpenTimelineIO by using +clips to represent media fragments. + +Status: + - Export of Media Playlists well supported + - Export of Master Playlists supported + - Import of Media Playlists well supported + - Import of Master Playlists unsupported + - Explicit Variant Stream controls in Master Playlists unsupported + +In general, you can author otio as follows: + t = otio.schema.Timeline() + track = otio.schema.Track("v1") + track.metadata['HLS'] = { + "EXT-X-INDEPENDENT-SEGMENTS": None, + "EXT-X-PLAYLIST-TYPE": "VOD" + } + t.tracks.append(track) + + # Make a prototype media ref with the fragment's initialization metadata + fragmented_media_ref = otio.schema.ExternalReference( + target_url='video1.mp4', + metadata={ + "streaming": { + "init_byterange": { + "byte_count": 729, + "byte_offset": 0 + }, + "init_uri": "media-video-1.mp4" + } + } + ) + + # Make a copy of the media ref specifying the byte range for the fragment + media_ref1 = fragmented_media_ref.deepcopy() + media_ref1.available_range=otio.opentime.TimeRange( + otio.opentime.RationalTime(0, 1), + otio.opentime.RationalTime(2.002, 1) + ) + media_ref1.metadata['streaming'].update( + { + "byte_count": 534220, + "byte_offset": 1361 + } + ) + + # make the fragment and append it + fragment1 = otio.schema.Clip(media_reference=media_ref1) + track.append(fragment1) + + # (repeat to define each fragment) + +The code above would yield an HLS playlist like: + #EXTM3U + #EXT-X-VERSION:7 + #EXT-X-TARGETDURATION:2 + #EXT-X-PLAYLIST-TYPE:VOD + #EXT-X-INDEPENDENT-SEGMENTS + #EXT-X-MEDIA-SEQUENCE:1 + #EXT-X-MAP:BYTERANGE="729@0",URI="media-video-1.mp4" + #EXTINF:2.00200, + #EXT-X-BYTERANGE:534220@1361 + video1.mp4 + #EXT-X-ENDLIST + +If you add min_segment_duration and max_segment_duration to the timeline's +metadata dictionary as RationalTime objects, you can control the rule set +deciding how many fragments to accumulate into a single segment. When nothing +is specified for these metadata keys, the adapter will create one segment per +fragment. + +In general, any metadata added to the track metadata dict under the HLS +namespace will be included at the top level of the exported playlist (see +``EXT-X-INDEPENDENT-SEGMENTS`` and ``EXT-X-PLAYLIST-TYPE`` in the example +above). Each segment will pass through any metadata in the HLS namespace from +the media_reference. + +If you write a Timeline with more than one track specified, then the adapter +will create an HLS master playlist. + +The following track metadata keys will be used to inform exported master +playlist metadata per variant stream: + bandwidth + codec + language + mimeType + group_id (audio) + autoselect (audio) + default (audio) +These values are translated to EXT-X-STREAM-INF and EXT-X-MEDIA +attributes as defined in sections 4.3.4.2 and 4.3.4.1 of +draft-pantos-http-live-streaming, respectively. +""" + +import re +import copy + +import opentimelineio as otio + +# TODO: determine output version based on features used +OUTPUT_PLAYLIST_VERSION = "7" + +# TODO: make sure all strings get sanitized through encoding and decoding +PLAYLIST_STRING_ENCODING = "utf-8" + +# Enable isinstance(my_instance, basestring) tests in Python 3 +# This can be phased out when Python 2 support is dropped. Replace tests with: +# isinstance(my_instance, str) + +try: + basestring +except NameError: + basestring = str + +""" +Matches a single key/value pair from an HLS Attribute List. +See section 4.2 of draft-pantos-http-live-streaming for more detail. +""" +ATTRIBUTE_RE = re.compile( + r'(?P[A-Z0-9-]+)' + r'\=' + + r'(?P(?:\"[^\r\n"]*\")|[^,]+)' + r',?' +) + +""" +Matches AttributeValue of the above regex into appropriate data types. +Note that these are meant to be joined using regex "or" in this order. +""" +_ATTRIBUTE_RE_VALUE_STR_LIST = [ + r'(?P(?P[0-9]+)x(?P[0-9]+))\Z', + r'(?P0[xX](?P[0-9A-F]+))\Z', + r'(?P-?[0-9]+\.[0-9]+)\Z', + r'(?P[0-9]+)\Z', + r'(?P\"(?P[^\r\n"]*)\")\Z', + r'(?P[^",\s]+)\Z' +] +ATTRIBUTE_VALUE_RE = re.compile("|".join(_ATTRIBUTE_RE_VALUE_STR_LIST)) + +""" +Matches a byterange as used in various contexts. +See section 4.3.2.2 of draft-pantos-http-live-streaming for an example use of +this byterange form. +""" +BYTERANGE_RE = re.compile(r'(?P\d+)(?:@(?P\d+))?') + +""" +Matches HLS Playlist tags or comments, respective. +See section 4.1 of draft-pantos-http-live-streaming for more detail. +""" +TAG_RE = re.compile( + r'#(?PEXT[^:\s]+)(?P:?)(?P.*)' +) +COMMENT_RE = re.compile(r'#(?!EXT)(?P.*)') + + +class AttributeListEnum(str): + """ A subclass allowing us to differentiate enums in HLS attribute lists + """ + + +def _value_from_raw_attribute_value(raw_attribute_value): + """ + Takes in a raw AttributeValue and returns an appopritate Python type. + If there is a problem decoding the value, None is returned. + """ + value_match = ATTRIBUTE_VALUE_RE.match(raw_attribute_value) + if not value_match: + return None + + group_dict = value_match.groupdict() + # suss out the match + for k, v in group_dict.items(): + # not a successful group match + if v is None: + continue + + # decode the string + if k == 'resolution': + return v + elif k == 'enumerated': + return AttributeListEnum(v) + elif k == 'hexcidecimal': + return int(group_dict['hex_value'], base=16) + elif k == 'floating_point': + return float(v) + elif k == 'decimal': + return int(v) + elif k == 'string': + # grab only the data within the quotes, excluding the quotes + string_value = group_dict['string_value'] + return string_value + + return None + + +class AttributeList(dict): + """ + Dictionary-like object representing an HLS AttributeList. + See section 4.2 of draft-pantos-http-live-streaming for more detail. + """ + + def __init__(self, other=None): + """ + contstructs an :class:`AttributeList`. + + ``Other`` can be either another dictionary-like object or a list of + key/value pairs + """ + if not other: + return + + try: + items = other.items() + except AttributeError: + items = other + + for k, v in items: + self[k] = v + + def __str__(self): + """ + Construct attribute list string as it would exist in an HLS playlist. + """ + attr_list_entries = [] + # Use a sorted version of the dictionary to ensure consistency + for k, v in sorted(self.items(), key=lambda i: i[0]): + out_value = '' + if isinstance(v, AttributeListEnum): + out_value = v + elif isinstance(v, basestring): + out_value = '"{}"'.format(v) + else: + out_value = str(v) + + attr_list_entries.append('{}={}'.format(k, out_value)) + + return ','.join(attr_list_entries) + + @classmethod + def from_string(cls, attrlist_string): + """ + Accepts an attribute list string and returns an :class:`AttributeList`. + + The values will be transformed to Python types. + """ + attr_list = cls() + match = ATTRIBUTE_RE.search(attrlist_string) + while match: + # unpack the values from the match + group_dict = match.groupdict() + name = group_dict['AttributeName'] + raw_value = group_dict['AttributeValue'] + + # parse the raw value + value = _value_from_raw_attribute_value(raw_value) + attr_list[name] = value + + # search for the next attribute in the string + match_end = match.span()[1] + match = ATTRIBUTE_RE.search(attrlist_string, match_end) + + return attr_list + + +# some special top-levle keys that HLS metadata will be decoded into +FORMAT_METADATA_KEY = 'HLS' +""" +Some concepts are translatable between HLS and other streaming formats (DASH). +These metadata keys are used on OTIO objects outside the HLS namespace because +they are higher level concepts. +""" +STREAMING_METADATA_KEY = 'streaming' +INIT_BYTERANGE_KEY = 'init_byterange' +INIT_URI_KEY = 'init_uri' +SEQUENCE_NUM_KEY = 'sequence_num' +BYTE_OFFSET_KEY = 'byte_offset' +BYTE_COUNT_KEY = 'byte_count' + + +class Byterange(object): + """Offers interpretation of HLS byte ranges in various forms.""" + + count = None + """(:class:`int`) Number of bytes included in the range.""" + + offset = None + """(:class:`int`) Byte offset at which the range starts.""" + + def __init__(self, count=None, offset=None): + """Constructs a :class:`Byterange` object. + + :param count: (:class:`int`) Number of bytes included in the range. + :param offset: (:class:`int`) Byte offset at which the range starts. + """ + self.count = (count if count is not None else 0) + self.offset = offset + + def __eq__(self, other): + if not isinstance(other, Byterange): + # fall back on identity, this should always be False + return (self is other) + return (self.count == other.count and self.offset == other.offset) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return '{}(offset = {}, count = {})'.format( + type(self), + str(self.offset), + str(self.count) + ) + + def __str__(self): + """returns a string in HLS format""" + + out_str = str(self.count) + if self.offset is not None: + out_str += '@{}'.format(str(self.offset)) + + return out_str + + def to_dict(self): + """Returns a dict suitable for storing in otio metadata. + + :return: (:class:`dict`) serializable version of byterange. + """ + range_dict = {BYTE_COUNT_KEY: self.count} + if self.offset is not None: + range_dict[BYTE_OFFSET_KEY] = self.offset + + return range_dict + + @classmethod + def from_string(cls, byterange_string): + """Construct a :class:`Byterange` given a string in HLS format. + + :param byterange_string: (:class:`str`) a byterange string. + :return: (:class:`Byterange`) The instance for the provided string. + """ + m = BYTERANGE_RE.match(byterange_string) + + return cls.from_match_dict(m.groupdict()) + + @classmethod + def from_match_dict(cls, match_dict): + """ + Construct a :class:`Byterange` given a groupdict from ``BYTERANGE_RE`` + + :param match_dict: (:class:`dict`) the ``match_dict``. + :return: (:class:`Byterange`) The instance for the provided string. + """ + byterange = cls(count=int(match_dict['n'])) + + try: + byterange.offset = int(match_dict['o']) + except KeyError: + pass + + return byterange + + @classmethod + def from_dict(cls, info_dict): + """ Creates a :class:`Byterange` given a dictionary containing keys + like generated from the :meth:`to_dict method`. + + :param info_dict: (:class:`dict`) Dictionary byterange. + :return: (:class:`Byterange`) an equivalent instance. + """ + byterange = cls( + count=info_dict.get(BYTE_COUNT_KEY), + offset=info_dict.get(BYTE_OFFSET_KEY) + ) + + return byterange + + +""" +For a given collection of media, HLS has two playlist types: + - Media Playlist + - Master Playlist + +The media playlist refers directly to the individual segments that make up an +audio or video track of a given program. The master playlist refers to a +collection of media playlists and provides ways to use them together +(rendition groups). + +See section 2 of draft-pantos-http-live-streaming for more detail. + +The constants below define which tags belong to which schema. +""" + +""" +Basic tags appear in both media and master playlists. +See section 4.3.1 of draft-pantos-http-live-streaming for more detail. +""" +BASIC_TAGS = set([ + "EXTM3U", + "EXT-X-VERSION" +]) + +""" +Media segment tags apply to either the following media or all subsequent +segments. They MUST NOT appear in master playlists. +See section 4.3.2 of draft-pantos-http-live-streaming for more detail. +""" +MEDIA_SEGMENT_TAGS = set([ + 'EXTINF', + 'EXT-X-BYTERANGE', + 'EXT-X-DISCONTINUITY', + 'EXT-X-KEY', + 'EXT-X-MAP', + 'EXT-X-PROGRAM-DATE-TIME', + 'EXT-X-DATERANGE' +]) + +""" The subset of above tags that apply to every segment following them """ +MEDIA_SEGMENT_SUBSEQUENT_TAGS = set([ + 'EXT-X-KEY', + 'EXT-X-MAP', +]) + +""" +Media Playlist tags must only occur once per playlist, and must not appear in +Master Playlists. +See section 4.3.3 of draft-pantos-http-live-streaming for more detail. +""" +MEDIA_PLAYLIST_TAGS = set([ + 'EXT-X-TARGETDURATION', + 'EXT-X-MEDIA-SEQUENCE', + 'EXT-X-DISCONTINUITY-SEQUENCE', + 'EXT-X-ENDLIST', + 'EXT-X-PLAYLIST-TYPE', + 'EXT-X-I-FRAMES-ONLY' +]) + +""" +Master playlist tags declare global parameters for the presentation. +They must not appear in media playlists. +See section 4.3.4 of draft-pantos-http-live-streaming for more detail. +""" +MASTER_PLAYLIST_TAGS = set([ + 'EXT-X-MEDIA', + 'EXT-X-STREAM-INF', + 'EXT-X-I-FRAME-STREAM-INF', + 'EXT-X-SESSION-DATA', + 'EXT-X-SESSION-KEY', +]) + +""" +Media or Master Playlist tags can appear in either media or master playlists. +See section 4.3.5 of draft-pantos-http-live-streaming for more detail. +These tags SHOULD appear in either the media or master playlist. If they occur +in both, their values MUST agree. +These values MUST NOT appear more than once in a playlist. +""" +MEDIA_OR_MASTER_TAGS = set([ + "EXT-X-INDEPENDENT-SEGMENTS", + "EXT-X-START" +]) + +""" +Some special tags used by the parser. +""" +PLAYLIST_START_TAG = "EXTM3U" +PLAYLIST_END_TAG = "EXT-X-ENDLIST" +PLAYLIST_VERSION_TAG = "EXT-X-VERSION" +PLAYLIST_SEGMENT_INF_TAG = "EXTINF" + +""" +attribute list entries to omit from EXT-I-FRAME-STREAM-INF tags +See section 4.3.4.3 of draft-pantos-http-live-streaming for more detail. +""" +I_FRAME_OMIT_ATTRS = set([ + 'FRAME-RATE', + 'AUDIO', + 'SUBTITLES', + 'CLOSED-CAPTIONS' +]) + +""" enum for kinds of playlist entries """ +EntryType = type('EntryType', (), { + 'tag': 'tag', + 'comment': 'comment', + 'URI': 'URI' +}) + +""" enum for types of playlists """ +PlaylistType = type('PlaylistType', (), { + 'media': 'media', + 'master': 'master' +}) + +""" mapping from HLS track type to otio ``TrackKind`` """ +HLS_TRACK_TYPE_TO_OTIO_KIND = { + AttributeListEnum('AUDIO'): otio.schema.TrackKind.Audio, + AttributeListEnum('VIDEO'): otio.schema.TrackKind.Video, + # TODO: determine how to handle SUBTITLES and CLOSED-CAPTIONS +} + +""" mapping from otio ``TrackKind`` to HLS track type """ +OTIO_TRACK_KIND_TO_HLS_TYPE = dict(( + (v, k) for k, v in HLS_TRACK_TYPE_TO_OTIO_KIND.items() +)) + + +class HLSPlaylistEntry(object): + """An entry in an HLS playlist. + + Entries can be a tag, a comment, or a URI. All HLS playlists are parsed + into lists of :class:`HLSPlaylistEntry` instances that can then be + interpreted against the HLS schema. + """ + + # TODO: rename this to entry_type to fix builtin masking + # type = None + """ (``EntryType``) the type of entry """ + + comment_string = None + """ + (:class:`str`) value of comment (if the ``entry_type`` is + ``EntryType.comment``). + """ + + tag_name = None + """ + (:class:`str`) Name of tag (if the ``entry_type`` is ``EntryType.tag``). + """ + + tag_value = None + """ + (:class:`str`) Value of tag (if the ``entry_type`` is ``EntryType.tag``). + """ + + uri = None + """ + (:class:`str`) Value of the URI (if the ``entry_type is ``EntryType.uri``). + """ + + def __init__(self, type): + """ + Constructs an :class:`HLSPlaylistEntry`. + + :param type: (``EntryType``) Type of entry. + """ + self.type = type + + def __repr__(self): + base_str = 'otio.adapter.HLSPlaylistEntry(type={}'.format( + self.type) + if self.type == EntryType.tag: + base_str += ', tag_name={}, tag_value={}'.format( + repr(self.tag_name), + repr(self.tag_value) + ) + elif self.type == EntryType.comment: + base_str += ', comment={}'.format(repr(self.comment_string)) + elif self.type == EntryType.URI: + base_str += ', URI={}'.format(repr(self.uri)) + + return base_str + ')' + + def __str__(self): + """ + Returns a string as it would appear in an HLS playlist. + + :return: (:class:`str`) HLS playlist entry string. + """ + if self.type == EntryType.comment and self.comment_string: + return "# {}".format(self.comment_string) + elif self.type == EntryType.comment: + # empty comments are blank lines + return "" + elif self.type == EntryType.URI: + return self.uri + elif self.type == EntryType.tag: + out_tag_name = self.tag_name + if self.tag_value is not None: + return '#{}:{}'.format(out_tag_name, self.tag_value) + else: + return '#{}'.format(out_tag_name) + + @classmethod + def tag_entry(cls, name, value=None): + """ + Creates an ``EntryType.tag`` :class:`HLSPlaylistEntry`. + + :param name: (:class:`str`) tag name. + :param value: (:class:`str`) tag value. + :return: (:class:`HLSPlaylistEntry`) Entry instance. + """ + entry = cls(EntryType.tag) + entry.tag_name = name + entry.tag_value = value + + return entry + + @classmethod + def comment_entry(cls, comment): + """Creates an ``EntryType.comment`` :class:`HLSPlaylistEntry`. + + :param comment: (:class:`str`) the comment. + :return: (:class:`HLSPlaylistEntry`) Entry instance. + """ + entry = cls(EntryType.comment) + entry.comment_string = comment + + return entry + + @classmethod + def uri_entry(cls, uri): + """Creates an ``EntryType.uri`` :class:`HLSPlaylistEntry`. + + :param uri: (:class:`str`) A URI string. + :return: (:class:`HLSPlaylistEntry`) Entry instance. + """ + entry = cls(EntryType.URI) + entry.uri = uri + + return entry + + @classmethod + def from_string(cls, entry_string): + """Creates an `:class:`HLSPlaylistEntry` given a string as it appears + in an HLS playlist. + + :param entry_string: (:class:`str`) String from an HLS playlist. + :return: (:class:`HLSPlaylistEntry`) Entry instance. + """ + # Empty lines are skipped + if not entry_string.strip(): + return None + + # Attempt to parse as a tag + m = TAG_RE.match(entry_string) + if m: + group_dict = m.groupdict() + tag_value = ( + group_dict['tagvalue'] + if group_dict['hasvalue'] else None + ) + entry = cls.tag_entry(group_dict['tagname'], tag_value) + return entry + + # Attempt to parse as a comment + m = COMMENT_RE.match(entry_string) + if m: + entry = cls.comment_entry(m.groupdict()['comment']) + return entry + + # If it's not the others, treat as a URI + entry = cls.uri_entry(entry_string) + + return entry + + """A dispatch dictionary for grabbing the right Regex to parse tags.""" + TAG_VALUE_RE_MAP = { + "EXTINF": re.compile(r'(?P\d+(\.\d*)?),(?P.*$)'), + "EXT-X-BYTERANGE": BYTERANGE_RE, + "EXT-X-KEY": re.compile(r'(?P<attribute_list>.*$)'), + "EXT-X-MAP": re.compile(r'(?P<attribute_list>.*$)'), + "EXT-X-MEDIA-SEQUENCE": re.compile(r'(?P<number>\d+)'), + "EXT-X-PLAYLIST-TYPE": re.compile(r'(?P<type>EVENT|VOD)'), + PLAYLIST_VERSION_TAG: re.compile(r'(?P<n>\d+)') + } + + def parsed_tag_value(self, playlist_version=None): + """Parses and returns ``self.tag_value`` based on the HLS schema. + + The value will be a dictionary where the keys are the names used in the + draft Pantos HTTP Live Streaming doc. When "attribute-list" is + specified, an entry "attribute_list" will be present containing + an :class:`AttributeList` instance. + + :param playlist_version: (:class:`int`) version number of the playlist. + If none is provided, a best guess will be made. + :return: The parsed value. + """ + if self.type != EntryType.tag: + return None + + try: + tag_re = self.TAG_VALUE_RE_MAP[self.tag_name] + except KeyError: + return None + + # parse the tag + m = tag_re.match(self.tag_value) + group_dict = m.groupdict() + + if not m: + return None + + # If the tag value has an attribute list, parse it and add it + try: + attribute_list = group_dict['attribute_list'] + attr_list = AttributeList.from_string(attribute_list) + group_dict['attributes'] = attr_list + except KeyError: + pass + + return group_dict + + +class HLSPlaylistParser(object): + """Bootstraps HLS parsing and hands the playlist string off to the + appropriate parser for the type + """ + + def __init__(self, edl_string): + self.timeline = otio.schema.Timeline() + self.playlist_type = None + + self._parse_playlist(edl_string) + + def _parse_playlist(self, edl_string): + """Parses the HLS Playlist string line-by-line.""" + # parse lines until we encounter one that identifies the playlist type + # then hand off + start_encountered = False + end_encountered = False + playlist_entries = [] + playlist_version = 1 + for line in edl_string.splitlines(): + # attempt to parse the entry + entry = HLSPlaylistEntry.from_string(line) + if entry is None: + continue + + entry_is_tag = (entry.type == EntryType.tag) + + # identify if the playlist start/end is encountered + if (entry_is_tag and not (start_encountered and end_encountered)): + if entry.tag_name == PLAYLIST_START_TAG: + start_encountered = True + elif entry.tag_name == PLAYLIST_END_TAG: + end_encountered = True + + # if the playlist starting tag hasn't been encountered, ignore + if not start_encountered: + continue + + # Store the parsed entry + playlist_entries.append(entry) + + # Determine if this tells us the playlist type + if not self.playlist_type and entry_is_tag: + if entry.tag_name in MASTER_PLAYLIST_TAGS: + self.playlist_type = PlaylistType.master + elif entry.tag_name in MEDIA_PLAYLIST_TAGS: + self.playlist_type = PlaylistType.media + + if end_encountered: + break + + # try to grab the version from the playlist + if entry_is_tag and entry.tag_name == PLAYLIST_VERSION_TAG: + playlist_version = int(entry.parsed_tag_value()['n']) + + # dispatch to the appropriate schema interpreter + if self.playlist_type is None: + self.timeline = None + raise otio.exceptions.ReadingNotSupportedError( + "could not determine playlist type" + ) + elif self.playlist_type == PlaylistType.master: + self.timeline = None + raise otio.exceptions.AdapterDoesntSupportFunction( + "HLS master playlists are not yet supported" + ) + elif self.playlist_type == PlaylistType.media: + parser = MediaPlaylistParser(playlist_entries, playlist_version) + if len(parser.track): + self.timeline.tracks.append(parser.track) + + +class MediaPlaylistParser(object): + """Parses an HLS Media playlist returning a SEQUENCE""" + + def __init__(self, playlist_entries, playlist_version=None): + self.track = otio.schema.Track( + metadata={FORMAT_METADATA_KEY: {}} + ) + + self._parse_entries(playlist_entries, playlist_version) + + def _handle_track_metadata(self, entry, playlist_version, clip): + """Stashes the tag value in the track metadata""" + value = entry.tag_value + self.track.metadata[FORMAT_METADATA_KEY][entry.tag_name] = value + + def _handle_discarded_metadata(self, entry, playlist_version, clip): + """Handler for tags that are discarded. This is done when a tag's + information is represented by the native OTIO concepts. + + For instance, the EXT-X-TARGETDURATION tag simply gives a rounded + value for the maximum segment size in the playlist. This can easily + be found in OTIO by examining the clips. + """ + # Do nothing + + def _metadata_dict_for_MAP(self, entry, playlist_version): + entry_data = entry.parsed_tag_value() + attributes = entry_data['attributes'] + map_dict = {} + for attr, value in attributes.items(): + if attr == 'BYTERANGE': + byterange = Byterange.from_string(value) + map_dict[INIT_BYTERANGE_KEY] = byterange.to_dict() + elif attr == 'URI': + map_dict[INIT_URI_KEY] = value + + return map_dict + + def _handle_INF(self, entry, playlist_version, clip): + # This specifies segment duration and optional title + info_dict = entry.parsed_tag_value(playlist_version) + segment_duration = float(info_dict['duration']) + segment_title = info_dict['title'] + available_range = otio.opentime.TimeRange( + otio.opentime.RationalTime(0, 1), + otio.opentime.RationalTime(segment_duration, 1) + ) + + # Push the info to the clip + clip.media_reference.available_range = available_range + clip.source_range = available_range + clip.name = segment_title + + def _handle_BYTERANGE(self, entry, playlist_version, clip): + reference_metadata = clip.media_reference.metadata + ref_streaming_metadata = reference_metadata.setdefault( + STREAMING_METADATA_KEY, + {} + ) + + # Pull out the byte count and offset + byterange = Byterange.from_match_dict( + entry.parsed_tag_value(playlist_version) + ) + ref_streaming_metadata.update(byterange.to_dict()) + + """ + Specifies handlers for specific HLS tags. + """ + TAG_HANDLERS = { + "EXTINF": _handle_INF, + PLAYLIST_VERSION_TAG: _handle_track_metadata, + "EXT-X-TARGETDURATION": _handle_discarded_metadata, + "EXT-X-MEDIA-SEQUENCE": _handle_discarded_metadata, + "EXT-X-PLAYLIST-TYPE": _handle_track_metadata, + "EXT-X-INDEPENDENT-SEGMENTS": _handle_track_metadata, + "EXT-X-BYTERANGE": _handle_BYTERANGE + } + + def _parse_entries(self, playlist_entries, playlist_version): + """Interpret the entries through the lens of the schema""" + current_clip = otio.schema.Clip( + media_reference=otio.schema.ExternalReference( + metadata={ + FORMAT_METADATA_KEY: {}, + STREAMING_METADATA_KEY: {} + } + ) + ) + current_media_ref = current_clip.media_reference + segment_metadata = {} + current_map_data = {} + # per section 4.3.3.2 of Pantos HLS, 0 is default start track + current_track = 0 + for entry in playlist_entries: + if entry.type == EntryType.URI: + # the URI ends the segment definition + current_media_ref.target_url = entry.uri + current_media_ref.metadata[FORMAT_METADATA_KEY].update( + segment_metadata + ) + current_media_ref.metadata[STREAMING_METADATA_KEY].update( + current_map_data + ) + current_clip.metadata.setdefault( + STREAMING_METADATA_KEY, + {} + )[SEQUENCE_NUM_KEY] = current_track + self.track.append(current_clip) + current_track += 1 + + # Set up the next segment definition + current_clip = otio.schema.Clip( + media_reference=otio.schema.ExternalReference( + metadata={ + FORMAT_METADATA_KEY: {}, + STREAMING_METADATA_KEY: {} + } + ) + ) + current_media_ref = current_clip.media_reference + continue + elif entry.type != EntryType.tag: + # the rest of the code deals only with tags + continue + + # Explode the EXT-X-MAP info out + if entry.tag_name == "EXT-X-MAP": + map_data = self._metadata_dict_for_MAP(entry, playlist_version) + current_map_data.update(map_data) + continue + + # Grab the track when it comes around + if entry.tag_name == "EXT-X-MEDIA-SEQUENCE": + entry_data = entry.parsed_tag_value() + current_track = int(entry_data['number']) + + # If the segment tag is one that applies to all that follow + # store the value to be applied to each segment + if entry.tag_name in MEDIA_SEGMENT_SUBSEQUENT_TAGS: + segment_metadata[entry.tag_name] = entry.tag_value + continue + + # use a handler if available + try: + handler = self.TAG_HANDLERS[entry.tag_name] + handler(self, entry, playlist_version, current_clip) + continue + except KeyError: + pass + + # add the tag to the reference metadata at the correct level + if entry.tag_name in [PLAYLIST_START_TAG, PLAYLIST_END_TAG]: + continue + elif entry.tag_name in MEDIA_SEGMENT_TAGS: + # Media segments translate into media refs + hls_metadata = current_media_ref.metadata[FORMAT_METADATA_KEY] + hls_metadata[entry.tag_name] = entry.tag_value + elif entry.tag_name in MEDIA_PLAYLIST_TAGS: + # Media playlists translate into tracks + hls_metadata = self.track.metadata[FORMAT_METADATA_KEY] + hls_metadata[entry.tag_name] = entry.tag_value + + +""" +Compatibility version list: + EXT-X-BYTERANGE >= 4 + EXT-X-I-FRAMES-ONLY >= 4 + EXT-X-MAP in media playlist with EXT-X-I-FRAMES-ONLY >= 5 + EXT-X-MAP in media playlist without I-FRAMES-ONLY >= 6 + EXT-X-KEY constrants are by attributes specified: + - IV >= 2 + - KEYFORMAT >= 5 + - KEYFORMATVERSIONS >= 5 + EXTINF with floating point vaules >= 3 + + master playlist: + EXT-X-MEDIA with INSTREAM-ID="SERVICE" +""" + + +def entries_for_segment( + uri, + segment_duration, + segment_name=None, + segment_byterange=None, + segment_tags=None +): + """Creates a set of :class:`HLSPlaylistEntries` with the given parameters. + + :param uri: (:class:`str`) The uri for the segment media. + :param segment_duration: (:class:`opentimelineio.opentime.RationalTime`) + playback duration of the segment. + :param segment_byterange: (:class:`ByteRange`) The data range for the + segment in the media (if required) + :param segment_tags: (:class:`dict`) key/value pairs of to become + additional tags for the segment + + :return: (:class:`list`) a group of :class:`HLSPlaylistEntry` instances for + the segment + """ + # Create the tags dict to build + if segment_tags: + tags = copy.deepcopy(segment_tags) + else: + tags = {} + + # Start building the entries list + segment_entries = [] + + # add the EXTINF + name = segment_name if segment_name is not None else '' + tag_value = '{0:.5f},{1}'.format( + otio.opentime.to_seconds(segment_duration), + name + ) + extinf_entry = HLSPlaylistEntry.tag_entry('EXTINF', tag_value) + segment_entries.append(extinf_entry) + + # add the additional tags + tag_entries = [ + HLSPlaylistEntry.tag_entry(k, v) for k, v in + tags.items() + ] + segment_entries.extend(tag_entries) + + # Now add the byterange for the entry + if segment_byterange: + byterange_entry = HLSPlaylistEntry.tag_entry( + 'EXT-X-BYTERANGE', + str(segment_byterange) + ) + segment_entries.append(byterange_entry) + + # Add the URI + # this method expects all fragments come from the same source file + uri_entry = HLSPlaylistEntry.uri_entry(uri) + segment_entries.append(uri_entry) + + return segment_entries + + +def stream_inf_attr_list_for_track(track): + """ Builds an :class:`AttributeList` instance for use in ``STREAM-INF`` + tags for the provided track. + + :param track: (:class:`otio.schema.Track`) A track representing a + variant stream + :return: (:class:`AttributeList`) The instance from the metadata + """ + streaming_metadata = track.metadata.get(STREAMING_METADATA_KEY, {}) + + attributes = [] + bandwidth = streaming_metadata.get('bandwidth') + if bandwidth is not None: + attributes.append(('BANDWIDTH', bandwidth)) + + codec = streaming_metadata.get('codec') + if codec is not None: + attributes.append(('CODECS', codec)) + + frame_rate = streaming_metadata.get('frame_rate') + if frame_rate is not None: + attributes.append(('FRAME-RATE', frame_rate)) + + if 'width' in streaming_metadata and 'height' in streaming_metadata: + resolution = "{}x{}".format( + streaming_metadata['width'], + streaming_metadata['height'] + ) + attributes.append(('RESOLUTION', AttributeListEnum(resolution))) + + al = AttributeList(attributes) + + return al + + +def master_playlist_to_string(master_timeline): + """Writes a master playlist describing the tracks""" + + # start with a version number of 1, as features are encountered, we will + # update the version accordingly + version_requirements = set([1]) + + # TODO: detect rather than forcing version 6 + version_requirements.add(6) + + header_tags = copy.copy( + master_timeline.metadata.get(FORMAT_METADATA_KEY, {}) + ) + + # Filter out any values from the HLS metadata that aren't meant to become + # tags, such as the directive to force an HLS master playlist + hls_md_blacklist = ['master_playlist'] + for key in hls_md_blacklist: + try: + del(header_tags[key]) + except KeyError: + pass + + playlist_entries = [] + + # First declare the non-visual media + hls_type_count = {} + video_tracks = [] + audio_tracks = [ + t for t in master_timeline.tracks if + t.kind == otio.schema.TrackKind.Audio + ] + for track in master_timeline.tracks: + if track.kind == otio.schema.TrackKind.Video: + # video is done later, skip + video_tracks.append(track) + continue + + # Determine the HLS type + hls_type = OTIO_TRACK_KIND_TO_HLS_TYPE[track.kind] + + streaming_metadata = track.metadata.get(STREAMING_METADATA_KEY, {}) + + # Find the group name + try: + group_id = streaming_metadata['group_id'] + except KeyError: + sub_id = hls_type_count.setdefault(hls_type, 1) + group_id = '{}{}'.format(hls_type, sub_id) + hls_type_count[hls_type] += 1 + + media_playlist_default_uri = "{}.m3u8".format(track.name) + try: + track_uri = track.metadata[FORMAT_METADATA_KEY].get( + 'uri', + media_playlist_default_uri + ) + except KeyError: + track_uri = media_playlist_default_uri + + # Build the attribute list + attributes = AttributeList( + [ + ('TYPE', hls_type), + ('GROUP-ID', group_id), + ('URI', track_uri), + ('NAME', track.name), + ] + ) + + if streaming_metadata.get('autoselect'): + attributes['AUTOSELECT'] = AttributeListEnum('YES') + + if streaming_metadata.get('default'): + attributes['DEFAULT'] = AttributeListEnum('YES') + + # Finally, create the tag + entry = HLSPlaylistEntry.tag_entry( + 'EXT-X-MEDIA', + str(attributes) + ) + + playlist_entries.append(entry) + + # Add a blank line in the playlist to separate sections + if playlist_entries: + playlist_entries.append(HLSPlaylistEntry.comment_entry('')) + + # First write any i-frame playlist entires + iframe_list_entries = [] + for track in video_tracks: + try: + iframe_uri = track.metadata[FORMAT_METADATA_KEY]['iframe_uri'] + except KeyError: + # don't include iframe playlist + continue + + # Create the attribute list + attribute_list = stream_inf_attr_list_for_track(track) + + # Remove entries to not be included for I-Frame streams + for attr in I_FRAME_OMIT_ATTRS: + try: + del(attribute_list[attr]) + except KeyError: + pass + + # Add the URI + attribute_list['URI'] = iframe_uri + + iframe_list_entries.append( + HLSPlaylistEntry.tag_entry( + 'EXT-X-I-FRAME-STREAM-INF', + str(attribute_list) + ) + ) + + if iframe_list_entries: + iframe_list_entries.append(HLSPlaylistEntry.comment_entry('')) + + playlist_entries.extend(iframe_list_entries) + + # Write an EXT-STREAM-INF for each rendition set + for track in video_tracks: + # create the base attribute list for the video track + al = stream_inf_attr_list_for_track(track) + + # Create the uri + media_playlist_default_uri = "{}.m3u8".format(track.name) + try: + track_uri = track.metadata[FORMAT_METADATA_KEY].get( + 'uri', media_playlist_default_uri + ) + except KeyError: + track_uri = media_playlist_default_uri + uri_entry = HLSPlaylistEntry.uri_entry(track_uri) + + # TODO: this will break when we have subtitle and CC tracks + added_entry = False + for audio_track in audio_tracks: + if track.name not in audio_track.metadata['linked_tracks']: + continue + + # Write an entry for using these together + try: + audio_track_streaming_metadata = audio_track.metadata[ + STREAMING_METADATA_KEY + ] + aud_group = audio_track_streaming_metadata['group_id'] + aud_codec = audio_track_streaming_metadata['codec'] + aud_bandwidth = audio_track_streaming_metadata['bandwidth'] + except KeyError: + raise TypeError( + "HLS audio tracks must have 'codec', 'group_id', and" + " 'bandwidth' specified in metadata" + ) + + combo_al = copy.copy(al) + combo_al['CODECS'] += ',{}'.format(aud_codec) + combo_al['AUDIO'] = aud_group + combo_al['BANDWIDTH'] += aud_bandwidth + + entry = HLSPlaylistEntry.tag_entry( + 'EXT-X-STREAM-INF', + str(combo_al) + ) + playlist_entries.append(entry) + playlist_entries.append(uri_entry) + + added_entry = True + + if not added_entry: + # write out one simple entry + entry = HLSPlaylistEntry.tag_entry( + 'EXT-X-STREAM-INF', + str(al) + ) + playlist_entries.append(entry) + playlist_entries.append(uri_entry) + + # add a break before the next grouping of entries + playlist_entries.append(HLSPlaylistEntry.comment_entry('')) + + out_entries = [HLSPlaylistEntry.tag_entry(PLAYLIST_START_TAG, None)] + + playlist_version = max(version_requirements) + playlist_version_entry = HLSPlaylistEntry.tag_entry( + PLAYLIST_VERSION_TAG, + str(playlist_version) + ) + + out_entries.append(playlist_version_entry) + + out_entries += ( + HLSPlaylistEntry.tag_entry(k, v) for k, v in header_tags.items() + ) + + # separate the header entries from the rest of the entries + out_entries.append(HLSPlaylistEntry.comment_entry('')) + + out_entries += playlist_entries + + playlist_string = '\n'.join( + (str(entry) for entry in out_entries) + ) + + return playlist_string + + +class MediaPlaylistWriter(): + + def __init__( + self, + media_track, + min_seg_duration=None, + max_seg_duration=None + ): + # Default to one segment per fragment + if min_seg_duration is None: + min_seg_duration = otio.opentime.RationalTime(0, 1) + if max_seg_duration is None: + max_seg_duration = otio.opentime.RationalTime(0, 1) + + self._min_seg_duration = min_seg_duration + self._max_seg_duration = max_seg_duration + + self._playlist_entries = [] + self._playlist_tags = {} + + # Whenever an entry is added that has a minimum version requirement, + # we add that version to this set. The max value from this set is the + # playlist's version requirement + self._versions_used = set([1]) + + # TODO: detect rather than forcing version 7 + self._versions_used.add(7) + + # Start the build + self._build_playlist_with_track(media_track) + + def _build_playlist_with_track(self, media_track): + """ + Executes methods to result in a fully populated _playlist_entries list + """ + self._copy_HLS_metadata(media_track) + self._setup_track_info(media_track) + self._add_segment_entries(media_track) + self._finalize_entries(media_track) + + def _copy_HLS_metadata(self, media_track): + """ + Copies any metadata in the "HLS" namespace from the track to the + playlist-global tags + """ + # Grab any metadata provided on the otio + try: + track_metadata = media_track.metadata[FORMAT_METADATA_KEY] + self._playlist_tags.update(track_metadata) + + # Remove the version tag from the track metadata, we'll compute + # based on what we write out + del(self._playlist_tags[PLAYLIST_VERSION_TAG]) + + except KeyError: + pass + + # additionally remove metadata keys added for providing master + # playlist URIs + for key in ('uri', 'iframe_uri'): + try: + del(self._playlist_tags[key]) + except KeyError: + pass + + def _setup_track_info(self, media_track): + """sets up playlist global metadata""" + + # Setup the track start + if 'EXT-X-I-FRAMES-ONLY' in media_track.metadata.get( + FORMAT_METADATA_KEY, + {} + ): + # I-Frame playlists start at zero no matter what + track_start = 0 + else: + # Pull the track num from the first clip, if provided + first_segment_streaming_metadata = media_track[0].metadata.get( + STREAMING_METADATA_KEY, + {} + ) + track_start = first_segment_streaming_metadata.get( + SEQUENCE_NUM_KEY + ) + + # If we found a track start or one isn't already set in the + # metadata, create the tag for it. + if ( + track_start is not None or + 'EXT-X-MEDIA-SEQUENCE' not in self._playlist_tags + ): + # Choose a reasonable track start default + if track_start is None: + track_start = 1 + self._playlist_tags['EXT-X-MEDIA-SEQUENCE'] = str(track_start) + + def _add_map_entry(self, fragment): + """adds an EXT-X-MAP entry from the given fragment + + returns the added entry + """ + + media_ref = fragment.media_reference + + # Extract useful tag data + media_ref_streaming_metadata = media_ref.metadata[ + STREAMING_METADATA_KEY + ] + uri = media_ref_streaming_metadata[INIT_URI_KEY] + seg_map_byterange_dict = media_ref_streaming_metadata.get( + INIT_BYTERANGE_KEY + ) + + # Create the attrlist + map_attr_list = AttributeList([ + ('URI', uri), + ]) + + # Add the byterange if provided + if seg_map_byterange_dict is not None: + seg_map_byterange = Byterange.from_dict(seg_map_byterange_dict) + map_attr_list['BYTERANGE'] = str(seg_map_byterange) + + # Construct the entry with the attrlist as the value + map_tag_str = str(map_attr_list) + entry = HLSPlaylistEntry.tag_entry("EXT-X-MAP", map_tag_str) + + self._playlist_entries.append(entry) + + return entry + + def _add_entries_for_segment_from_fragments( + self, + fragments, + omit_hls_keys=None, + is_iframe_playlist=False + ): + """ + For the given list of otio clips representing fragments in the mp4, + add playlist entries for single HLS segment. + + :param fragments: (:clas:`list`) :class:`opentimelineio.schema.Clip` + objects to write as a contiguous segment. + :param omit_hls_keys: (:class:`list`) metadata keys from the original + "HLS" metadata namespeaces will not be passed through. + :param is_iframe_playlist: (:class:`bool`) If true, writes one segment + per fragment, otherwise writes all fragments as a single segment + + :return: (:class:`list` the :class:`HLSPlaylistEntry` instances added + to the playlist + """ + if is_iframe_playlist: + entries = [] + for fragment in fragments: + name = '' + fragment_range = Byterange.from_dict( + fragment.media_reference.metadata[STREAMING_METADATA_KEY] + ) + + segment_tags = {} + frag_tags = fragment.media_reference.metadata.get( + FORMAT_METADATA_KEY, + {} + ) + segment_tags.update(copy.deepcopy(frag_tags)) + + # scrub any metadata marked for omission + omit_hls_keys = omit_hls_keys or [] + for key in omit_hls_keys: + try: + del(segment_tags[key]) + except KeyError: + pass + + segment_entries = entries_for_segment( + fragment.media_reference.target_url, + fragment.duration(), + name, + fragment_range, + segment_tags + ) + entries.extend(segment_entries) + + self._playlist_entries.extend(entries) + return entries + + segment_tags = {} + for fragment in fragments: + frag_tags = fragment.media_reference.metadata.get( + FORMAT_METADATA_KEY, + {} + ) + segment_tags.update(copy.deepcopy(frag_tags)) + + # scrub any metadata marked for omission + omit_hls_keys = omit_hls_keys or [] + for key in omit_hls_keys: + try: + del(segment_tags[key]) + except KeyError: + pass + + # Calculate the byterange for the segment (if byteranges are specified) + first_ref = fragments[0].media_reference + first_ref_streaming_md = first_ref.metadata[STREAMING_METADATA_KEY] + if 'byte_offset' in first_ref_streaming_md and len(fragments) == 1: + segment_range = Byterange.from_dict(first_ref_streaming_md) + elif 'byte_offset' in first_ref_streaming_md: + # Find the byterange encapsulating everything + last_ref = fragments[-1].media_reference + last_ref_streaming_md = last_ref.metadata[STREAMING_METADATA_KEY] + first_range = Byterange.from_dict(first_ref_streaming_md) + last_range = Byterange.from_dict(last_ref_streaming_md) + + segment_offset = first_range.offset + segment_end = (last_range.offset + last_range.count) + segment_count = segment_end - segment_offset + segment_range = Byterange(segment_count, segment_offset) + else: + segment_range = None + + uri = fragments[0].media_reference.target_url + + # calculate the combined duration + segment_duration = fragments[0].duration() + for frag in fragments[1:]: + segment_duration += frag.duration() + + # TODO: Determine how to pass a segment name in + segment_name = '' + segment_entries = entries_for_segment( + uri, + segment_duration, + segment_name, + segment_range, + segment_tags + ) + + self._playlist_entries.extend(segment_entries) + return segment_entries + + def _fragments_have_same_map(self, fragment, following_fragment): + """ + Given fragment and following_fragment, returns whether or not their + initialization data is the same (what becomes EXT-X-MAP) + """ + media_ref = fragment.media_reference + media_ref_streaming_md = media_ref.metadata.get( + STREAMING_METADATA_KEY, + {} + ) + following_ref = following_fragment.media_reference + following_ref_streaming_md = following_ref.metadata.get( + STREAMING_METADATA_KEY, + {} + ) + # Check the init file + init_uri = media_ref_streaming_md.get(INIT_URI_KEY) + following_init_uri = media_ref_streaming_md.get(INIT_URI_KEY) + if init_uri != following_init_uri: + return False + + # Check the init byterange + init_dict = media_ref_streaming_md.get(INIT_BYTERANGE_KEY) + following_init_dict = following_ref_streaming_md.get( + INIT_BYTERANGE_KEY + ) + + dummy_range = Byterange(0, 0) + init_range = ( + Byterange.from_dict(init_dict) if init_dict else dummy_range + ) + following_range = ( + Byterange.from_dict(following_init_dict) + if following_init_dict else dummy_range + ) + + if init_range != following_range: + return False + + return True + + def _fragments_are_contiguous(self, fragment, following_fragment): + """ Given fragment and following_fragment (otio clips) returns whether + or not they are contiguous. + + To be contiguous the fragments must: + 1. have the same file URL + 2. have the same initialization data (what becomes EXT-X-MAP) + 3. be adjacent in the file (follwoing_fragment's first byte directly + follows fragment's last byte) + + Returns True if following_fragment is contiguous from fragment + """ + # Fragments are contiguous if: + # 1. They have the file url + # 2. They have the same map info + # 3. Their byte ranges are contiguous + media_ref = fragment.media_reference + media_ref_streaming_md = media_ref.metadata.get( + STREAMING_METADATA_KEY, + {} + ) + following_ref = following_fragment.media_reference + following_ref_streaming_md = following_ref.metadata.get( + STREAMING_METADATA_KEY, + {} + ) + if media_ref.target_url != following_ref.target_url: + return False + + if ( + media_ref_streaming_md.get(INIT_URI_KEY) != + following_ref_streaming_md.get(INIT_URI_KEY) + ): + return False + + if not self._fragments_have_same_map(fragment, following_fragment): + return False + + # Check if fragments are contiguous in file + try: + frag_end = ( + media_ref_streaming_md['byte_offset'] + + media_ref_streaming_md['byte_count'] + ) + if frag_end != following_ref_streaming_md['byte_offset']: + return False + except KeyError: + return False + + # since we haven't returned yet, all checks must have passed! + return True + + def _add_segment_entries(self, media_track): + """given a media track, generates the segment entries""" + + # Determine whether or not this is an I-Frame playlist + track_hls_metadata = media_track.metadata.get('HLS') + is_iframe_playlist = 'EXT-X-I-FRAMES-ONLY' in track_hls_metadata + + # Make a list copy of the fragments + fragments = [clip for clip in media_track] + + segment_durations = [] + previous_fragment = None + map_changed = True + while fragments: + # There should be at least one fragment per segment + frag_it = iter(fragments) + first_frag = next(frag_it) + gathered_fragments = [first_frag] + gathered_duration = first_frag.duration() + + # Determine this segment will need a new EXT-X-MAP entry + map_changed = ( + True if previous_fragment is None else + not self._fragments_have_same_map( + previous_fragment, + first_frag + ) + ) + + # Iterate through the remaining fragments until a discontinuity + # is found, our time limit is met, or we add all the fragments to + # the segment + for fragment in frag_it: + # Determine whther or not the fragments are contiguous + previous_fragment = gathered_fragments[-1] + contiguous = self._fragments_are_contiguous( + previous_fragment, + fragment + ) + + # Determine if we've hit our segment time conditions + new_duration = gathered_duration + fragment.duration() + segment_full = ( + gathered_duration >= self._min_seg_duration or + new_duration > self._max_seg_duration + ) + + # End condition met, cut the segment + if not contiguous or segment_full: + break + + # Include the fragment + gathered_duration = new_duration + gathered_fragments.append(fragment) + + # Write out the segment and start the next + start_fragment = gathered_fragments[0] + + # If the map for this segment was a change, write it + if map_changed: + self._add_map_entry(start_fragment) + + # add the entries for the segment. Omit any EXT-X-MAP metadata + # that may have come in from reading a file (we're updating) + self._add_entries_for_segment_from_fragments( + gathered_fragments, + omit_hls_keys=('EXT-X-MAP'), + is_iframe_playlist=is_iframe_playlist + ) + + duration_seconds = otio.opentime.to_seconds(gathered_duration) + segment_durations.append(duration_seconds) + + # in the next iteration, start where we left off + fragments = fragments[len(gathered_fragments):] + + # Set the max segment duration + max_duration = round(max(segment_durations)) + self._playlist_tags['EXT-X-TARGETDURATION'] = str(int(max_duration)) + + def _finalize_entries(self, media_track): + """Does final wrap-up of playlist entries""" + + self._playlist_tags['EXT-X-PLAYLIST-TYPE'] = 'VOD' + + # add the end + end_entry = HLSPlaylistEntry.tag_entry(PLAYLIST_END_TAG) + self._playlist_entries.append(end_entry) + + # find the maximum HLS feature version we've used + playlist_version = max(self._versions_used) + playlist_version_entry = HLSPlaylistEntry.tag_entry( + PLAYLIST_VERSION_TAG, + str(playlist_version) + ) + + # now that we know what was used, let's prepend the header + playlist_header_entries = [ + HLSPlaylistEntry.tag_entry(PLAYLIST_START_TAG), + playlist_version_entry + ] + + # add in the rest of the header entries in a deterministic order + playlist_header_entries += ( + HLSPlaylistEntry.tag_entry(k, v) + for k, v in sorted(self._playlist_tags.items(), key=lambda i: i[0]) + ) + + # Prepend the entries with the header entries + self._playlist_entries = ( + playlist_header_entries + self._playlist_entries + ) + + def playlist_string(self): + """Returns the string representation of the playlist entries""" + + return '\n'.join( + (str(entry) for entry in self._playlist_entries) + ) + +# Public interface + + +def read_from_string(input_str): + """Adapter entry point for reading.""" + + parser = HLSPlaylistParser(input_str) + return parser.timeline + + +def write_to_string(input_otio): + """Adapter entry point for writing.""" + + if len(input_otio.tracks) == 0: + return None + + # Determine whether we should write a media or master playlist + try: + write_master = input_otio.metadata['HLS']['master_playlist'] + except KeyError: + # If no explicit directive, infer + write_master = (len(input_otio.tracks) > 1) + + if write_master: + return master_playlist_to_string(input_otio) + else: + media_track = input_otio.tracks[0] + track_streaming_md = input_otio.metadata.get( + STREAMING_METADATA_KEY, + {} + ) + min_seg_duration = track_streaming_md.get('min_segment_duration') + max_seg_duration = track_streaming_md.get('max_segment_duration') + + writer = MediaPlaylistWriter( + media_track, + min_seg_duration, + max_seg_duration + ) + return writer.playlist_string() diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/maya_sequencer.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/maya_sequencer.py new file mode 100644 index 0000000000..03e6cf8763 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/maya_sequencer.py @@ -0,0 +1,132 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""Maya Sequencer Adapter Harness""" + +import os +import subprocess + +from .. import adapters + + +def write_to_file(input_otio, filepath): + if "OTIO_MAYA_PYTHON_BIN" not in os.environ: + raise RuntimeError( + "'OTIO_MAYA_PYTHON_BIN' not set, please set this to path to " + "mayapy within the Maya installation." + ) + maya_python_path = os.environ["OTIO_MAYA_PYTHON_BIN"] + if not os.path.exists(maya_python_path): + raise RuntimeError( + 'Cannot access file at OTIO_MAYA_PYTHON_BIN: "{}"'.format( + maya_python_path + ) + ) + if os.path.isdir(maya_python_path): + raise RuntimeError( + "OTIO_MAYA_PYTHON_BIN contains a path to a directory, not to an " + "executable file: {}".format(maya_python_path) + ) + + input_data = adapters.write_to_string(input_otio, "otio_json") + + os.environ['PYTHONPATH'] = ( + os.pathsep.join( + [ + os.environ.setdefault('PYTHONPATH', ''), + os.path.dirname(__file__) + ] + ) + ) + + proc = subprocess.Popen( + [ + os.environ["OTIO_MAYA_PYTHON_BIN"], + '-m', + 'extern_maya_sequencer', + 'write', + filepath + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + env=os.environ + ) + proc.stdin.write(input_data) + out, err = proc.communicate() + + if proc.returncode: + raise RuntimeError( + "ERROR: extern_maya_sequencer (called through the maya sequencer " + "file adapter) failed. stderr output: " + err + ) + + +def read_from_file(filepath): + if "OTIO_MAYA_PYTHON_BIN" not in os.environ: + raise RuntimeError( + "'OTIO_MAYA_PYTHON_BIN' not set, please set this to path to " + "mayapy within the Maya installation." + ) + + os.environ['PYTHONPATH'] = ( + os.pathsep.join( + [ + os.environ.setdefault('PYTHONPATH', ''), + os.path.dirname(__file__) + ] + ) + ) + + proc = subprocess.Popen( + [ + os.environ["OTIO_MAYA_PYTHON_BIN"], + '-m', + 'extern_maya_sequencer', + 'read', + filepath + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + env=os.environ + ) + out, err = proc.communicate() + + # maya probably puts a bunch of crap on the stdout + sentinel_str = "OTIO_JSON_BEGIN\n" + end_sentinel_str = "\nOTIO_JSON_END\n" + start = out.find(sentinel_str) + end = out.find(end_sentinel_str) + result = adapters.read_from_string( + out[start + len(sentinel_str):end], + "otio_json" + ) + + if proc.returncode: + raise RuntimeError( + "ERROR: extern_maya_sequencer (called through the maya sequencer " + "file adapter) failed. stderr output: " + err + ) + return result diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/rv.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/rv.py new file mode 100644 index 0000000000..33d00ce8c7 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/rv.py @@ -0,0 +1,84 @@ +# +# Copyright 2017 Pixar Animation Studios +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""RvSession Adapter harness""" + +import subprocess +import os +import copy + +from .. import adapters + + +def write_to_file(input_otio, filepath): + if "OTIO_RV_PYTHON_BIN" not in os.environ: + raise RuntimeError( + "'OTIO_RV_PYTHON_BIN' not set, please set this to path to " + "py-interp within the RV installation." + ) + + if "OTIO_RV_PYTHON_LIB" not in os.environ: + raise RuntimeError( + "'OTIO_RV_PYTHON_LIB' not set, please set this to path to python " + "directory within the RV installation." + ) + + input_data = adapters.write_to_string(input_otio, "otio_json") + + base_environment = copy.deepcopy(os.environ) + + base_environment['PYTHONPATH'] = ( + os.pathsep.join( + [ + base_environment.setdefault('PYTHONPATH', ''), + os.path.dirname(__file__) + ] + ) + ) + + proc = subprocess.Popen( + [ + base_environment["OTIO_RV_PYTHON_BIN"], + '-m', + 'extern_rv', + filepath + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + env=base_environment + ) + proc.stdin.write(input_data) + out, err = proc.communicate() + + if out.strip(): + print("stdout: {}".format(out)) + if err.strip(): + print("stderr: {}".format(err)) + + if proc.returncode: + raise RuntimeError( + "ERROR: extern_rv (called through the rv session file adapter) " + "failed. stderr output: " + err + ) diff --git a/pype/vendor/python/python_2/opentimelineio_contrib/adapters/xges.py b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/xges.py new file mode 100644 index 0000000000..525a8a4649 --- /dev/null +++ b/pype/vendor/python/python_2/opentimelineio_contrib/adapters/xges.py @@ -0,0 +1,819 @@ +# +# Copyright (C) 2019 Igalia S.L +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +"""OpenTimelineIO GStreamer Editing Services XML Adapter. """ +import re +import unittest + +from decimal import Decimal +from fractions import Fraction +from xml.etree import cElementTree +from xml.dom import minidom +import opentimelineio as otio + +META_NAMESPACE = "XGES" + + +FRAMERATE_FRAMEDURATION = {23.98: "24000/1001", + 24: "600/25", + 25: "25/1", + 29.97: "30000/1001", + 30: "30/1", + 50: "50/1", + 59.94: "60000/1001", + 60: "60/1"} + + +TRANSITION_MAP = { + "crossfade": otio.schema.TransitionTypes.SMPTE_Dissolve +} +# Two way map +TRANSITION_MAP.update(dict([(v, k) for k, v in TRANSITION_MAP.items()])) + + +class GstParseError(otio.exceptions.OTIOError): + pass + + +class GstStructure(object): + """ + GstStructure parser with a "dictionary" like API. + """ + UNESCAPE = re.compile(r'(?<!\\)\\(.)') + INT_TYPES = "".join( + ("int", "uint", "int8", "uint8", "int16", + "uint16", "int32", "uint32", "int64", "uint64") + ) + + def __init__(self, text): + self.text = text + self.modified = False + self.name, self.types, self.values = GstStructure._parse(text + ";") + + def __repr__(self): + if not self.modified: + return self.text + + res = self.name + for key, value in self.values.items(): + value_type = self.types[key] + res += ', %s=(%s)"%s"' % (key, value_type, self.escape(value)) + res += ';' + + return res + + def __getitem__(self, key): + return self.values[key] + + def set(self, key, value_type, value): + if self.types.get(key) == value_type and self.values.get(key) == value: + return + + self.modified = True + self.types[key] = value_type + self.values[key] = value + + def get(self, key, default=None): + return self.values.get(key, default) + + @staticmethod + def _find_eos(s): + # find next '"' without preceeding '\' + line = 0 + while 1: # faster than regexp for '[^\\]\"' + p = s.index('"') + line += p + 1 + if s[p - 1] != '\\': + return line + s = s[(p + 1):] + return -1 + + @staticmethod + def escape(s): + # XXX: The unicode type doesn't exist in Python 3 (all strings are unicode) + # so we have to use type(u"") which works in both Python 2 and 3. + if type(s) not in (str, type(u"")): + return s + return s.replace(" ", "\\ ") + + @staticmethod + def _parse(s): + in_string = s + types = {} + values = {} + scan = True + # parse id + p = s.find(',') + if p == -1: + try: + p = s.index(';') + except ValueError: + p = len(s) + scan = False + name = s[:p] + # parse fields + while scan: + comma_space_it = p + # skip 'name, ' / 'value, ' + while s[comma_space_it] in [' ', ',']: + comma_space_it += 1 + s = s[comma_space_it:] + p = s.index('=') + k = s[:p] + if not s[p + 1] == '(': + raise ValueError("In %s position: %d" % (in_string, p)) + s = s[(p + 2):] # skip 'key=(' + p = s.index(')') + t = s[:p] + s = s[(p + 1):] # skip 'type)' + + if s[0] == '"': + s = s[1:] # skip '"' + p = GstStructure._find_eos(s) + if p == -1: + raise ValueError + v = s[:(p - 1)] + if s[p] == ';': + scan = False + # unescape \., but not \\. (using a backref) + # need a reverse for re.escape() + v = v.replace('\\\\', '\\') + v = GstStructure.UNESCAPE.sub(r'\1', v) + else: + p = s.find(',') + if p == -1: + p = s.index(';') + scan = False + v = s[:p] + + if t == 'structure': + v = GstStructure(v) + elif t == 'string' and len(v) and v[0] == '"': + v = v[1:-1] + elif t == 'boolean': + v = (v == '1') + elif t in GstStructure.INT_TYPES: + v = int(v) + types[k] = t + values[k] = v + + return (name, types, values) + + +class GESTrackType: + UNKNOWN = 1 << 0 + AUDIO = 1 << 1 + VIDEO = 1 << 2 + TEXT = 1 << 3 + CUSTOM = 1 << 4 + + @staticmethod + def to_otio_type(_type): + if _type == GESTrackType.AUDIO: + return otio.schema.TrackKind.Audio + elif _type == GESTrackType.VIDEO: + return otio.schema.TrackKind.Video + + raise GstParseError("Can't translate track type %s" % _type) + + +GST_CLOCK_TIME_NONE = 18446744073709551615 +GST_SECOND = 1000000000 + + +def to_gstclocktime(rational_time): + """ + This converts a RationalTime object to a GstClockTime + + Args: + rational_time (RationalTime): This is a RationalTime object + + Returns: + int: A time in nanosecond + """ + + return int(rational_time.value_rescaled_to(1) * GST_SECOND) + + +def get_from_structure(xmlelement, fieldname, default=None, attribute="properties"): + structure = GstStructure(xmlelement.get(attribute, attribute)) + return structure.get(fieldname, default) + + +class XGES: + """ + This object is responsible for knowing how to convert an xGES + project into an otio timeline + """ + + def __init__(self, xml_string): + self.xges_xml = cElementTree.fromstring(xml_string) + self.rate = 25 + + def _set_rate_from_timeline(self, timeline): + metas = GstStructure(timeline.attrib.get("metadatas", "metadatas")) + framerate = metas.get("framerate") + if framerate: + rate = Fraction(framerate) + else: + video_track = timeline.find("./track[@track-type='4']") + rate = None + if video_track is not None: + properties = GstStructure( + video_track.get("properties", "properties;")) + restriction_caps = GstStructure(properties.get( + "restriction-caps", "restriction-caps")) + rate = restriction_caps.get("framerate") + + if rate is None: + return + + self.rate = float(Fraction(rate)) + if self.rate == int(self.rate): + self.rate = int(self.rate) + else: + self.rate = float(round(Decimal(self.rate), 2)) + + def to_rational_time(self, ns_timestamp): + """ + This converts a GstClockTime value to an otio RationalTime object + + Args: + ns_timestamp (int): This is a GstClockTime value (nanosecond absolute value) + + Returns: + RationalTime: A RationalTime object + """ + return otio.opentime.RationalTime(round(int(ns_timestamp) / + (GST_SECOND / self.rate)), self.rate) + + def to_otio(self): + """ + Convert an xges to an otio + + Returns: + OpenTimeline: An OpenTimeline Timeline object + """ + + project = self.xges_xml.find("./project") + metas = GstStructure(project.attrib.get("metadatas", "metadatas")) + otio_project = otio.schema.SerializableCollection( + name=metas.get('name'), + metadata={ + META_NAMESPACE: {"metadatas": project.attrib.get( + "metadatas", "metadatas")} + } + ) + timeline = project.find("./timeline") + self._set_rate_from_timeline(timeline) + + otio_timeline = otio.schema.Timeline( + name=metas.get('name', "unnamed"), + metadata={ + META_NAMESPACE: { + "metadatas": timeline.attrib.get("metadatas", "metadatas"), + "properties": timeline.attrib.get("properties", "properties") + } + } + ) + + all_names = set() + self._add_layers(timeline, otio_timeline, all_names) + otio_project.append(otio_timeline) + + return otio_project + + def _add_layers(self, timeline, otio_timeline, all_names): + for layer in timeline.findall("./layer"): + tracks = self._build_tracks_from_layer_clips(layer, all_names) + otio_timeline.tracks.extend(tracks) + + def _get_clips_for_type(self, clips, track_type): + if not clips: + return False + + clips_for_type = [] + for clip in clips: + if int(clip.attrib['track-types']) & track_type: + clips_for_type.append(clip) + + return clips_for_type + + def _build_tracks_from_layer_clips(self, layer, all_names): + all_clips = layer.findall('./clip') + + tracks = [] + for track_type in [GESTrackType.VIDEO, GESTrackType.AUDIO]: + clips = self._get_clips_for_type(all_clips, track_type) + if not clips: + continue + + track = otio.schema.Track() + track.kind = GESTrackType.to_otio_type(track_type) + self._add_clips_in_track(clips, track, all_names) + + tracks.append(track) + + return tracks + + def _add_clips_in_track(self, clips, track, all_names): + for clip in clips: + otio_clip = self._create_otio_clip(clip, all_names) + if otio_clip is None: + continue + + clip_offset = self.to_rational_time(int(clip.attrib['start'])) + if clip_offset > track.duration(): + track.append( + self._create_otio_gap( + 0, + (clip_offset - track.duration()) + ) + ) + + track.append(otio_clip) + + return track + + def _get_clip_name(self, clip, all_names): + i = 0 + tmpname = name = clip.get("name", GstStructure( + clip.get("properties", "properties;")).get("name")) + while True: + if tmpname not in all_names: + all_names.add(tmpname) + return tmpname + + i += 1 + tmpname = name + '_%d' % i + + def _create_otio_transition(self, clip, all_names): + start = self.to_rational_time(clip.attrib["start"]) + end = start + self.to_rational_time(clip.attrib["duration"]) + cut_point = otio.opentime.RationalTime((end.value - start.value) / + 2, start.rate) + + return otio.schema.Transition( + name=self._get_clip_name(clip, all_names), + transition_type=TRANSITION_MAP.get( + clip.attrib["asset-id"], otio.schema.TransitionTypes.Custom + ), + in_offset=cut_point, + out_offset=cut_point, + ) + + def _create_otio_uri_clip(self, clip, all_names): + source_range = otio.opentime.TimeRange( + start_time=self.to_rational_time(clip.attrib["inpoint"]), + duration=self.to_rational_time(clip.attrib["duration"]), + ) + + otio_clip = otio.schema.Clip( + name=self._get_clip_name(clip, all_names), + source_range=source_range, + media_reference=self._reference_from_id( + clip.get("asset-id"), clip.get("type-name")), + ) + + return otio_clip + + def _create_otio_clip(self, clip, all_names): + otio_clip = None + + if clip.get("type-name") == "GESTransitionClip": + otio_clip = self._create_otio_transition(clip, all_names) + elif clip.get("type-name") == "GESUriClip": + otio_clip = self._create_otio_uri_clip(clip, all_names) + + if otio_clip is None: + print("Could not represent: %s" % clip.attrib) + return None + + otio_clip.metadata[META_NAMESPACE] = { + "properties": clip.get("properties", "properties;"), + "metadatas": clip.get("metadatas", "metadatas;"), + } + + return otio_clip + + def _create_otio_gap(self, start, duration): + source_range = otio.opentime.TimeRange( + start_time=otio.opentime.RationalTime(start), + duration=duration + ) + return otio.schema.Gap(source_range=source_range) + + def _reference_from_id(self, asset_id, asset_type="GESUriClip"): + asset = self._asset_by_id(asset_id, asset_type) + if asset is None: + return None + if not asset.get("id", ""): + return otio.schema.MissingReference() + + duration = GST_CLOCK_TIME_NONE + if asset_type == "GESUriClip": + duration = get_from_structure(asset, "duration", duration) + + available_range = otio.opentime.TimeRange( + start_time=self.to_rational_time(0), + duration=self.to_rational_time(duration) + ) + ref = otio.schema.ExternalReference( + target_url=asset.get("id"), + available_range=available_range + ) + + ref.metadata[META_NAMESPACE] = { + "properties": asset.get("properties"), + "metadatas": asset.get("metadatas"), + } + + return ref + + # -------------------- + # search helpers + # -------------------- + def _asset_by_id(self, asset_id, asset_type): + return self.xges_xml.find( + "./project/ressources/asset[@id='{}'][@extractable-type-name='{}']".format( + asset_id, asset_type) + ) + + def _timeline_element_by_name(self, timeline, name): + for clip in timeline.findall("./layer/clip"): + if get_from_structure(clip, 'name') == name: + return clip + + return None + + +class XGESOtio: + + def __init__(self, input_otio): + self.container = input_otio + self.rate = 25 + + def _insert_new_sub_element(self, into_parent, tag, attrib=None, text=''): + elem = cElementTree.SubElement(into_parent, tag, **attrib or {}) + elem.text = text + return elem + + def _get_element_properties(self, element): + return element.metadata.get(META_NAMESPACE, {}).get("properties", "properties;") + + def _get_element_metadatas(self, element): + return element.metadata.get(META_NAMESPACE, + {"GES": {}}).get("metadatas", "metadatas;") + + def _serialize_ressource(self, ressources, ressource, asset_type): + if isinstance(ressource, otio.schema.MissingReference): + return + + if ressources.find("./asset[@id='%s'][@extractable-type-name='%s']" % ( + ressource.target_url, asset_type)) is not None: + return + + properties = GstStructure(self._get_element_properties(ressource)) + if properties.get('duration') is None: + properties.set('duration', 'guin64', + to_gstclocktime(ressource.available_range.duration)) + + self._insert_new_sub_element( + ressources, 'asset', + attrib={ + "id": ressource.target_url, + "extractable-type-name": 'GESUriClip', + "properties": str(properties), + "metadatas": self._get_element_metadatas(ressource), + } + ) + + def _get_transition_times(self, offset, otio_transition): + rational_offset = otio.opentime.RationalTime( + round(int(offset) / (GST_SECOND / self.rate)), + self.rate + ) + start = rational_offset - otio_transition.in_offset + end = rational_offset + otio_transition.out_offset + + return 0, to_gstclocktime(start), to_gstclocktime(end - start) + + def _serialize_clip( + self, + otio_track, + layer, + layer_priority, + ressources, + otio_clip, + clip_id, + offset + ): + + # FIXME - Figure out a proper way to determine clip type! + asset_id = "GESTitleClip" + asset_type = "GESTitleClip" + + if isinstance(otio_clip, otio.schema.Transition): + asset_type = "GESTransitionClip" + asset_id = TRANSITION_MAP.get(otio_clip.transition_type, "crossfade") + inpoint, offset, duration = self._get_transition_times(offset, otio_clip) + else: + inpoint = to_gstclocktime(otio_clip.source_range.start_time) + duration = to_gstclocktime(otio_clip.source_range.duration) + + if not isinstance(otio_clip.media_reference, otio.schema.MissingReference): + asset_id = otio_clip.media_reference.target_url + asset_type = "GESUriClip" + + self._serialize_ressource(ressources, otio_clip.media_reference, + asset_type) + + if otio_track.kind == otio.schema.TrackKind.Audio: + track_types = GESTrackType.AUDIO + elif otio_track.kind == otio.schema.TrackKind.Video: + track_types = GESTrackType.VIDEO + else: + raise ValueError("Unhandled track type: %s" % otio_track.kind) + + properties = otio_clip.metadata.get( + META_NAMESPACE, + { + "properties": 'properties, name=(string)"%s"' % ( + GstStructure.escape(otio_clip.name) + ) + }).get("properties") + return self._insert_new_sub_element( + layer, 'clip', + attrib={ + "id": str(clip_id), + "properties": properties, + "asset-id": str(asset_id), + "type-name": str(asset_type), + "track-types": str(track_types), + "layer-priority": str(layer_priority), + "start": str(offset), + "rate": '0', + "inpoint": str(inpoint), + "duration": str(duration), + "metadatas": self._get_element_metadatas(otio_clip), + } + ) + + def _serialize_tracks(self, timeline, otio_timeline): + audio_vals = ( + 'properties', + 'restriction-caps=(string)audio/x-raw(ANY)', + 'framerate=(GstFraction)1', + otio_timeline.duration().rate + ) + + properties = '%s, %s,%s/%s' % audio_vals + self._insert_new_sub_element( + timeline, 'track', + attrib={ + "caps": "audio/x-raw(ANY)", + "track-type": '2', + 'track-id': '0', + 'properties': properties + } + ) + + video_vals = ( + 'properties', + 'restriction-caps=(string)video/x-raw(ANY)', + 'framerate=(GstFraction)1', + otio_timeline.duration().rate + ) + + properties = '%s, %s,%s/%s' % video_vals + for otio_track in otio_timeline.tracks: + if otio_track.kind == otio.schema.TrackKind.Video: + self._insert_new_sub_element( + timeline, 'track', + attrib={ + "caps": "video/x-raw(ANY)", + "track-type": '4', + 'track-id': '1', + 'properties': properties, + } + ) + + return + + def _serialize_layer(self, timeline, layers, layer_priority): + if layer_priority not in layers: + layers[layer_priority] = self._insert_new_sub_element( + timeline, 'layer', + attrib={ + "priority": str(layer_priority), + } + ) + + def _serialize_timeline_element(self, timeline, layers, layer_priority, + offset, otio_track, otio_element, + ressources, all_clips): + self._serialize_layer(timeline, layers, layer_priority) + layer = layers[layer_priority] + if isinstance(otio_element, (otio.schema.Clip, otio.schema.Transition)): + element = self._serialize_clip(otio_track, layer, layer_priority, + ressources, otio_element, + str(len(all_clips)), offset) + all_clips.add(element) + if isinstance(otio_element, otio.schema.Transition): + # Make next clip overlap + return int(element.get("start")) - offset + elif not isinstance(otio_element, otio.schema.Gap): + print("FIXME: Add support for %s" % type(otio_element)) + return 0 + + return to_gstclocktime(otio_element.source_range.duration) + + def _make_element_names_unique(self, all_names, otio_element): + if isinstance(otio_element, otio.schema.Gap): + return + + if not isinstance(otio_element, otio.schema.Track): + i = 0 + name = otio_element.name + while True: + if name not in all_names: + otio_element.name = name + break + + i += 1 + name = otio_element.name + '_%d' % i + all_names.add(otio_element.name) + + if isinstance(otio_element, (otio.schema.Stack, otio.schema.Track)): + for sub_element in otio_element: + self._make_element_names_unique(all_names, sub_element) + + def _make_timeline_elements_names_unique(self, otio_timeline): + element_names = set() + for track in otio_timeline.tracks: + for element in track: + self._make_element_names_unique(element_names, element) + + def _serialize_timeline(self, project, ressources, otio_timeline): + metadatas = GstStructure(self._get_element_metadatas(otio_timeline)) + metadatas.set( + "framerate", "fraction", self._framerate_to_frame_duration( + otio_timeline.duration().rate + ) + ) + timeline = self._insert_new_sub_element( + project, 'timeline', + attrib={ + "properties": self._get_element_properties(otio_timeline), + "metadatas": str(metadatas), + } + ) + self._serialize_tracks(timeline, otio_timeline) + + self._make_timeline_elements_names_unique(otio_timeline) + + all_clips = set() + layers = {} + for layer_priority, otio_track in enumerate(otio_timeline.tracks): + self._serialize_layer(timeline, layers, layer_priority) + offset = 0 + for otio_element in otio_track: + offset += self._serialize_timeline_element( + timeline, layers, layer_priority, offset, + otio_track, otio_element, ressources, all_clips, + ) + + for layer in layers.values(): + layer[:] = sorted(layer, key=lambda child: int(child.get("start"))) + + # -------------------- + # static methods + # -------------------- + @staticmethod + def _framerate_to_frame_duration(framerate): + frame_duration = FRAMERATE_FRAMEDURATION.get(int(framerate), "") + if not frame_duration: + frame_duration = FRAMERATE_FRAMEDURATION.get(float(framerate), "") + return frame_duration + + def to_xges(self): + xges = cElementTree.Element('ges', version="0.4") + + metadatas = GstStructure(self._get_element_metadatas(self.container)) + if self.container.name is not None: + metadatas.set("name", "string", self.container.name) + if not isinstance(self.container, otio.schema.Timeline): + project = self._insert_new_sub_element( + xges, 'project', + attrib={ + "properties": self._get_element_properties(self.container), + "metadatas": str(metadatas), + } + ) + + if len(self.container) > 1: + print( + "WARNING: Only one timeline supported, using *only* the first one.") + + otio_timeline = self.container[0] + + else: + project = self._insert_new_sub_element( + xges, 'project', + attrib={ + "metadatas": str(metadatas), + } + ) + otio_timeline = self.container + + ressources = self._insert_new_sub_element(project, 'ressources') + self.rate = otio_timeline.duration().rate + self._serialize_timeline(project, ressources, otio_timeline) + + # with indentations. + string = cElementTree.tostring(xges, encoding="UTF-8") + dom = minidom.parseString(string) + return dom.toprettyxml(indent=' ') + + +# -------------------- +# adapter requirements +# -------------------- +def read_from_string(input_str): + """ + Necessary read method for otio adapter + + Args: + input_str (str): A GStreamer Editing Services formated project + + Returns: + OpenTimeline: An OpenTimeline object + """ + + return XGES(input_str).to_otio() + + +def write_to_string(input_otio): + """ + Necessary write method for otio adapter + + Args: + input_otio (OpenTimeline): An OpenTimeline object + + Returns: + str: The string contents of an FCP X XML + """ + + return XGESOtio(input_otio).to_xges() + + +# -------------------- +# Some unit check for internal types +# -------------------- + +class XGESTests(unittest.TestCase): + + def test_gst_structure_parsing(self): + struct = GstStructure('properties, name=(string)"%s";' % ( + GstStructure.escape("sc01 sh010_anim.mov")) + ) + self.assertEqual(struct["name"], "sc01 sh010_anim.mov") + + def test_gst_structure_editing(self): + struct = GstStructure('properties, name=(string)"%s";' % ( + GstStructure.escape("sc01 sh010_anim.mov")) + ) + self.assertEqual(struct["name"], "sc01 sh010_anim.mov") + + struct.set("name", "string", "test") + self.assertEqual(struct["name"], "test") + self.assertEqual(str(struct), 'properties, name=(string)"test";') + + def test_empty_string(self): + struct = GstStructure('properties, name=(string)"";') + self.assertEqual(struct["name"], "") + + +if __name__ == '__main__': + unittest.main() From 824be75d537947249937f94c90357902fe43ca46 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 17:04:05 +0200 Subject: [PATCH 176/295] created new project config schema validating new keys --- schema/config-2.0.json | 87 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 schema/config-2.0.json diff --git a/schema/config-2.0.json b/schema/config-2.0.json new file mode 100644 index 0000000000..098d1983e2 --- /dev/null +++ b/schema/config-2.0.json @@ -0,0 +1,87 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "pype:config-2.0", + "description": "A project configuration.", + + "type": "object", + + "additionalProperties": false, + "required": [ + "tasks", + "apps" + ], + + "properties": { + "schema": { + "description": "Schema identifier for payload", + "type": "string" + }, + "templates": { + "type": "object" + }, + "roots": { + "type": "object" + }, + "imageio": { + "type": "object" + }, + "tasks": { + "type": "object", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "group": {"type": "string"}, + "label": {"type": "string"} + }, + "required": [ + "short_name" + ] + } + }, + "apps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "group": {"type": "string"}, + "label": {"type": "string"} + }, + "required": ["name"] + } + }, + "families": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "label": {"type": "string"}, + "hideFilter": {"type": "boolean"} + }, + "required": ["name"] + } + }, + "groups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "color": {"type": "string"}, + "order": {"type": ["integer", "number"]} + }, + "required": ["name"] + } + }, + "copy": { + "type": "object" + } + } +} From 43ac74c752e7bbd93f788e098091d3b6fcde49ce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 17:04:22 +0200 Subject: [PATCH 177/295] created new project schema using new config reference --- schema/project-3.0.json | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 schema/project-3.0.json diff --git a/schema/project-3.0.json b/schema/project-3.0.json new file mode 100644 index 0000000000..d6368d665c --- /dev/null +++ b/schema/project-3.0.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "pype:project-3.0", + "description": "A unit of data", + + "type": "object", + + "additionalProperties": true, + + "required": [ + "schema", + "type", + "name", + "data", + "config" + ], + + "properties": { + "schema": { + "description": "Schema identifier for payload", + "type": "string", + "enum": ["pype:project-3.0"], + "example": "pype:project-3.0" + }, + "type": { + "description": "The type of document", + "type": "string", + "enum": ["project"], + "example": "project" + }, + "parent": { + "description": "Unique identifier to parent document", + "example": "592c33475f8c1b064c4d1696" + }, + "name": { + "description": "Name of directory", + "type": "string", + "pattern": "^[a-zA-Z0-9_.]*$", + "example": "hulk" + }, + "data": { + "description": "Document metadata", + "type": "object", + "example": { + "fps": 24, + "width": 1920, + "height": 1080 + } + }, + "config": { + "type": "object", + "description": "Document metadata", + "$ref": "config-2.0.json" + } + }, + + "definitions": {} +} From 302a00c9c95a032deb2966f18e7e9f3582b0fdc8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 17:04:58 +0200 Subject: [PATCH 178/295] sync to avalon is using new schemas --- pype/modules/ftrack/lib/avalon_sync.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 970a270290..43e02283c2 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -31,9 +31,9 @@ log = Logger.get_logger(__name__) # Current schemas for avalon types EntitySchemas = { - "project": "pype:project-2.1", + "project": "pype:project-3.0", "asset": "pype:asset-3.0", - "config": "pype:config-1.1" + "config": "pype:config-2.0" } # Group name of custom attributes From 7a45a1a0e7003c198efa2aa07943b446e5a7b371 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 17:05:19 +0200 Subject: [PATCH 179/295] anatomy handler can handle not existing projects --- pype/settings/handlers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 6e93f2f405..0a60f6ab2c 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -610,6 +610,9 @@ class MongoSettingsHandler(SettingsHandler): Probably should fill missing keys and values. """ + if not project_doc: + return {} + attributes = {} project_doc_data = project_doc.get("data") or {} for key in self.attribute_keys: From c5b10b9214995e0b3b370cabc1cedfeff449594c Mon Sep 17 00:00:00 2001 From: Petr Kalis <petr.kalis@gmail.com> Date: Tue, 30 Mar 2021 17:47:24 +0200 Subject: [PATCH 180/295] Fix - handle duplication of Task name If Task name is explicitly set in template, it duplicated it here. Task name doesnt need to be in template, but by standard it should be in subset name. This whole replace situation is because of avalon's Creator which modify subset name even if it shouldn't. If Creator app is reworked (could have wide impact!), this should be cleaned up. --- .../harmony/plugins/publish/collect_farm_render.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pype/hosts/harmony/plugins/publish/collect_farm_render.py b/pype/hosts/harmony/plugins/publish/collect_farm_render.py index 98706ad951..c283b7f8da 100644 --- a/pype/hosts/harmony/plugins/publish/collect_farm_render.py +++ b/pype/hosts/harmony/plugins/publish/collect_farm_render.py @@ -124,10 +124,16 @@ class CollectFarmRender(pype.lib.abstract_collect_render. # TODO: handle pixel aspect and frame step # TODO: set Deadline stuff (pools, priority, etc. by presets) # because of using 'renderFarm' as a family, replace 'Farm' with - # capitalized task name - subset_name = node.split("/")[1].replace( + # capitalized task name - issue of avalon-core Creator app + subset_name = node.split("/")[1] + task_name = context.data["anatomyData"]["task"].capitalize() + replace_str = "" + if task_name.lower() not in subset_name.lower(): + replace_str = task_name + subset_name = subset_name.replace( 'Farm', - context.data["anatomyData"]["task"].capitalize()) + replace_str) + render_instance = HarmonyRenderInstance( version=version, time=api.time(), From 52b1619b50158baa578607600511c3138c929981 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 17:52:50 +0200 Subject: [PATCH 181/295] removed env_group_key from application schemas --- .../system_settings/applications.json | 443 +++--------------- .../host_settings/schema_aftereffects.json | 3 +- .../host_settings/schema_blender.json | 3 +- .../host_settings/schema_celaction.json | 3 +- .../host_settings/schema_djv.json | 3 +- .../host_settings/schema_fusion.json | 3 +- .../host_settings/schema_harmony.json | 3 +- .../host_settings/schema_houdini.json | 3 +- .../host_settings/schema_maya.json | 3 +- .../host_settings/schema_mayabatch.json | 3 +- .../host_settings/schema_photoshop.json | 3 +- .../host_settings/schema_resolve.json | 3 +- .../host_settings/schema_shell.json | 3 +- .../host_settings/schema_tvpaint.json | 3 +- .../host_settings/schema_unreal.json | 3 +- .../host_settings/template_host_variant.json | 3 +- .../host_settings/template_nuke.json | 3 +- 17 files changed, 77 insertions(+), 414 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index ea910e125d..08e7a16599 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -16,18 +16,7 @@ "MAYA_DISABLE_CER": "Yes", "PYMEL_SKIP_MEL_INIT": "Yes", "LC_ALL": "C", - "PYPE_LOG_NO_COLORS": "Yes", - "__environment_keys__": { - "maya": [ - "PYTHONPATH", - "MAYA_DISABLE_CLIC_IPM", - "MAYA_DISABLE_CIP", - "MAYA_DISABLE_CER", - "PYMEL_SKIP_MEL_INIT", - "LC_ALL", - "PYPE_LOG_NO_COLORS" - ] - } + "PYPE_LOG_NO_COLORS": "Yes" }, "variants": { "maya_2020": { @@ -50,12 +39,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2020", - "__environment_keys__": { - "maya_2020": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2020" } }, "maya_2019": { @@ -78,12 +62,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2019", - "__environment_keys__": { - "maya_2019": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2019" } }, "maya_2018": { @@ -106,12 +85,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2018", - "__environment_keys__": { - "maya_2018": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2018" } } } @@ -134,19 +108,7 @@ "PYMEL_SKIP_MEL_INIT": "Yes", "LC_ALL": "C", "PYPE_LOG_NO_COLORS": "Yes", - "MAYA_TEST": "{MAYA_VERSION}", - "__environment_keys__": { - "mayabatch": [ - "PYTHONPATH", - "MAYA_DISABLE_CLIC_IPM", - "MAYA_DISABLE_CIP", - "MAYA_DISABLE_CER", - "PYMEL_SKIP_MEL_INIT", - "LC_ALL", - "PYPE_LOG_NO_COLORS", - "MAYA_TEST" - ] - } + "MAYA_TEST": "{MAYA_VERSION}" }, "variants": { "mayabatch_2020": { @@ -167,12 +129,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2020", - "__environment_keys__": { - "mayabatch_2020": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2020" } }, "mayabatch_2019": { @@ -193,12 +150,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2019", - "__environment_keys__": { - "mayabatch_2019": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2019" } }, "mayabatch_2018": { @@ -219,12 +171,7 @@ "linux": [] }, "environment": { - "MAYA_VERSION": "2018", - "__environment_keys__": { - "mayabatch_2018": [ - "MAYA_VERSION" - ] - } + "MAYA_VERSION": "2018" } } } @@ -243,14 +190,7 @@ "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" }, - "LOGLEVEL": "DEBUG", - "__environment_keys__": { - "nuke": [ - "NUKE_PATH", - "PATH", - "LOGLEVEL" - ] - } + "LOGLEVEL": "DEBUG" }, "variants": { "nuke_12-2": { @@ -272,11 +212,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "nuke_12-2": [] - } - } + "environment": {} }, "nuke_12-0": { "enabled": true, @@ -297,11 +233,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "nuke_12-0": [] - } - } + "environment": {} }, "nuke_11-3": { "enabled": true, @@ -322,11 +254,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "nuke_11-3": [] - } - } + "environment": {} }, "nuke_11-2": { "enabled": true, @@ -345,11 +273,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "nuke_11-2": [] - } - } + "environment": {} } } }, @@ -367,14 +291,7 @@ "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" }, - "LOGLEVEL": "DEBUG", - "__environment_keys__": { - "nukex": [ - "NUKE_PATH", - "PATH", - "LOGLEVEL" - ] - } + "LOGLEVEL": "DEBUG" }, "variants": { "nukex_12-2": { @@ -402,11 +319,7 @@ "--nukex" ] }, - "environment": { - "__environment_keys__": { - "nukex_12-2": [] - } - } + "environment": {} }, "nukex_12-0": { "enabled": true, @@ -433,11 +346,7 @@ "--nukex" ] }, - "environment": { - "__environment_keys__": { - "nukex_12-0": [] - } - } + "environment": {} }, "nukex_11-3": { "enabled": true, @@ -464,11 +373,7 @@ "--nukex" ] }, - "environment": { - "__environment_keys__": { - "nukex_11-3": [] - } - } + "environment": {} }, "nukex_11-2": { "enabled": true, @@ -493,11 +398,7 @@ "--nukex" ] }, - "environment": { - "__environment_keys__": { - "nukex_11-2": [] - } - } + "environment": {} } } }, @@ -515,16 +416,7 @@ }, "WORKFILES_STARTUP": "0", "TAG_ASSETBUILD_STARTUP": "0", - "LOGLEVEL": "DEBUG", - "__environment_keys__": { - "nukestudio": [ - "HIERO_PLUGIN_PATH", - "PATH", - "WORKFILES_STARTUP", - "TAG_ASSETBUILD_STARTUP", - "LOGLEVEL" - ] - } + "LOGLEVEL": "DEBUG" }, "variants": { "nukestudio_12-2": { @@ -552,11 +444,7 @@ "--studio" ] }, - "environment": { - "__environment_keys__": { - "nukestudio_12-2": [] - } - } + "environment": {} }, "nukestudio_12-0": { "enabled": true, @@ -583,11 +471,7 @@ "--studio" ] }, - "environment": { - "__environment_keys__": { - "nukestudio_12-0": [] - } - } + "environment": {} }, "nukestudio_11-3": { "enabled": true, @@ -614,11 +498,7 @@ "--studio" ] }, - "environment": { - "__environment_keys__": { - "nukestudio_11-3": [] - } - } + "environment": {} }, "nukestudio_11-2": { "enabled": true, @@ -641,11 +521,7 @@ "--studio" ] }, - "environment": { - "__environment_keys__": { - "nukestudio_11-2": [] - } - } + "environment": {} } } }, @@ -663,16 +539,7 @@ }, "WORKFILES_STARTUP": "0", "TAG_ASSETBUILD_STARTUP": "0", - "LOGLEVEL": "DEBUG", - "__environment_keys__": { - "hiero": [ - "HIERO_PLUGIN_PATH", - "PATH", - "WORKFILES_STARTUP", - "TAG_ASSETBUILD_STARTUP", - "LOGLEVEL" - ] - } + "LOGLEVEL": "DEBUG" }, "variants": { "hiero_12-2": { @@ -700,11 +567,7 @@ "--hiero" ] }, - "environment": { - "__environment_keys__": { - "hiero_12-2": [] - } - } + "environment": {} }, "hiero_12-0": { "enabled": true, @@ -731,11 +594,7 @@ "--hiero" ] }, - "environment": { - "__environment_keys__": { - "hiero_12-0": [] - } - } + "environment": {} }, "hiero_11-3": { "enabled": true, @@ -762,11 +621,7 @@ "--hiero" ] }, - "environment": { - "__environment_keys__": { - "hiero_11-3": [] - } - } + "environment": {} }, "hiero_11-2": { "enabled": true, @@ -791,11 +646,7 @@ "--hiero" ] }, - "environment": { - "__environment_keys__": { - "hiero_11-2": [] - } - } + "environment": {} } } }, @@ -826,17 +677,7 @@ "{PYTHON36}/Scripts", "{PATH}" ], - "PYPE_LOG_NO_COLORS": "Yes", - "__environment_keys__": { - "fusion": [ - "FUSION_UTILITY_SCRIPTS_SOURCE_DIR", - "FUSION_UTILITY_SCRIPTS_DIR", - "PYTHON36", - "PYTHONPATH", - "PATH", - "PYPE_LOG_NO_COLORS" - ] - } + "PYPE_LOG_NO_COLORS": "Yes" }, "variants": { "fusion_16": { @@ -854,11 +695,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "fusion_16": [] - } - } + "environment": {} }, "fusion_9": { "enabled": true, @@ -877,11 +714,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "fusion_9": [] - } - } + "environment": {} } } }, @@ -926,21 +759,7 @@ ], "PRE_PYTHON_SCRIPT": "{PYPE_ROOT}/pype/resolve/preload_console.py", "PYPE_LOG_NO_COLORS": "True", - "RESOLVE_DEV": "True", - "__environment_keys__": { - "resolve": [ - "RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR", - "RESOLVE_SCRIPT_API", - "RESOLVE_SCRIPT_LIB", - "RESOLVE_UTILITY_SCRIPTS_DIR", - "PYTHON36_RESOLVE", - "PYTHONPATH", - "PATH", - "PRE_PYTHON_SCRIPT", - "PYPE_LOG_NO_COLORS", - "RESOLVE_DEV" - ] - } + "RESOLVE_DEV": "True" }, "variants": { "resolve_16": { @@ -960,11 +779,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "resolve_16": [] - } - } + "environment": {} } } }, @@ -983,12 +798,6 @@ "darwin": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", "linux": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", "windows": "{PYPE_ROOT}/pype/hosts/houdini/startup;&" - }, - "__environment_keys__": { - "houdini": [ - "HOUDINI_PATH", - "HOUDINI_MENU_PATH" - ] } }, "variants": { @@ -1009,11 +818,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "houdini_18-5": [] - } - } + "environment": {} }, "houdini_18": { "enabled": true, @@ -1030,11 +835,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "houdini_18": [] - } - } + "environment": {} }, "houdini_17": { "enabled": true, @@ -1051,11 +852,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "houdini_17": [] - } - } + "environment": {} } } }, @@ -1070,14 +867,7 @@ "{PYPE_REPOS_ROOT}/avalon-core/setup/blender", "{PYTHONPATH}" ], - "CREATE_NEW_CONSOLE": "yes", - "__environment_keys__": { - "blender": [ - "BLENDER_USER_SCRIPTS", - "PYTHONPATH", - "CREATE_NEW_CONSOLE" - ] - } + "CREATE_NEW_CONSOLE": "yes" }, "variants": { "blender_2-83": { @@ -1103,11 +893,7 @@ "--python-use-system-env" ] }, - "environment": { - "__environment_keys__": { - "blender_2-83": [] - } - } + "environment": {} }, "blender_2-90": { "enabled": true, @@ -1132,11 +918,7 @@ "--python-use-system-env" ] }, - "environment": { - "__environment_keys__": { - "blender_2-90": [] - } - } + "environment": {} } } }, @@ -1147,13 +929,7 @@ "host_name": "harmony", "environment": { "AVALON_HARMONY_WORKFILES_ON_LAUNCH": "1", - "LIB_OPENHARMONY_PATH": "{PYPE_ROOT}/pype/vendor/OpenHarmony", - "__environment_keys__": { - "harmony": [ - "AVALON_HARMONY_WORKFILES_ON_LAUNCH", - "LIB_OPENHARMONY_PATH" - ] - } + "LIB_OPENHARMONY_PATH": "{PYPE_ROOT}/pype/vendor/OpenHarmony" }, "variants": { "harmony_20": { @@ -1171,11 +947,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "harmony_20": [] - } - } + "environment": {} }, "harmony_17": { "enabled": true, @@ -1194,11 +966,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "harmony_17": [] - } - } + "environment": {} } } }, @@ -1208,12 +976,7 @@ "icon": "{}/app_icons/tvpaint.png", "host_name": "tvpaint", "environment": { - "PYPE_LOG_NO_COLORS": "True", - "__environment_keys__": { - "tvpaint": [ - "PYPE_LOG_NO_COLORS" - ] - } + "PYPE_LOG_NO_COLORS": "True" }, "variants": { "tvpaint_animation_11-64bits": { @@ -1233,11 +996,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "tvpaint_animation_11-64bits": [] - } - } + "environment": {} }, "tvpaint_animation_11-32bits": { "enabled": true, @@ -1256,11 +1015,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "tvpaint_animation_11-32bits": [] - } - } + "environment": {} } } }, @@ -1273,15 +1028,7 @@ "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH": "1", "PYPE_LOG_NO_COLORS": "Yes", "WEBSOCKET_URL": "ws://localhost:8099/ws/", - "WORKFILES_SAVE_AS": "Yes", - "__environment_keys__": { - "photoshop": [ - "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH", - "PYPE_LOG_NO_COLORS", - "WEBSOCKET_URL", - "WORKFILES_SAVE_AS" - ] - } + "WORKFILES_SAVE_AS": "Yes" }, "variants": { "photoshop_2020": { @@ -1301,11 +1048,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "photoshop_2020": [] - } - } + "environment": {} }, "photoshop_2021": { "enabled": true, @@ -1324,11 +1067,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "photoshop_2021": [] - } - } + "environment": {} } } }, @@ -1341,15 +1080,7 @@ "AVALON_AFTEREFFECTS_WORKFILES_ON_LAUNCH": "1", "PYPE_LOG_NO_COLORS": "Yes", "WEBSOCKET_URL": "ws://localhost:8097/ws/", - "WORKFILES_SAVE_AS": "Yes", - "__environment_keys__": { - "aftereffects": [ - "AVALON_AFTEREFFECTS_WORKFILES_ON_LAUNCH", - "PYPE_LOG_NO_COLORS", - "WEBSOCKET_URL", - "WORKFILES_SAVE_AS" - ] - } + "WORKFILES_SAVE_AS": "Yes" }, "variants": { "aftereffects_2020": { @@ -1369,11 +1100,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "aftereffects_2020": [] - } - } + "environment": {} }, "aftereffects_2021": { "enabled": true, @@ -1392,11 +1119,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "aftereffects_2021": [] - } - } + "environment": {} } } }, @@ -1406,12 +1129,7 @@ "icon": "app_icons/celaction.png", "host_name": "celaction", "environment": { - "CELACTION_TEMPLATE": "{PYPE_ROOT}/pype/hosts/celaction/celaction_template_scene.scn", - "__environment_keys__": { - "celaction": [ - "CELACTION_TEMPLATE" - ] - } + "CELACTION_TEMPLATE": "{PYPE_ROOT}/pype/hosts/celaction/celaction_template_scene.scn" }, "variants": { "celation_Local": { @@ -1425,11 +1143,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "celation_Local": [] - } - } + "environment": {} } } }, @@ -1441,14 +1155,7 @@ "environment": { "AVALON_UNREAL_PLUGIN": "{PYPE_REPOS_ROOT}/avalon-unreal-integration", "PYPE_LOG_NO_COLORS": "True", - "QT_PREFERRED_BINDING": "PySide", - "__environment_keys__": { - "unreal": [ - "AVALON_UNREAL_PLUGIN", - "PYPE_LOG_NO_COLORS", - "QT_PREFERRED_BINDING" - ] - } + "QT_PREFERRED_BINDING": "PySide" }, "variants": { "unreal_4-24": { @@ -1466,21 +1173,13 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "unreal_4-24": [] - } - } + "environment": {} } } }, "shell": { "enabled": true, - "environment": { - "__environment_keys__": { - "shell": [] - } - }, + "environment": {}, "variants": { "python_python_3-7": { "enabled": true, @@ -1497,11 +1196,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "python_python_3-7": [] - } - } + "environment": {} }, "python_python_2-7": { "enabled": true, @@ -1518,11 +1213,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "python_python_2-7": [] - } - } + "environment": {} }, "terminal_terminal": { "enabled": true, @@ -1539,11 +1230,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "terminal_terminal": [] - } - } + "environment": {} } } }, @@ -1552,11 +1239,7 @@ "label": "DJV View", "icon": "{}/app_icons/djvView.png", "host_name": "", - "environment": { - "__environment_keys__": { - "djvview": [] - } - }, + "environment": {}, "variants": { "djvview_1-1": { "enabled": true, @@ -1573,11 +1256,7 @@ "darwin": [], "linux": [] }, - "environment": { - "__environment_keys__": { - "djvview_1-1": [] - } - } + "environment": {} } } } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json index 6e1ba352fc..cd080bf0f2 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_aftereffects.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "aftereffects" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json index 5030f8280f..2501e94b50 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_blender.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "blender" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json index c5fe824f94..fbdad62a92 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "celaction" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json index 3f3af3585a..381437d4ff 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_djv.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "djvview" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index d693c39ffe..8661916d06 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "fusion" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json index 8ad07c95ba..7c59b0febd 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_harmony.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "harmony" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json index 7698cb4cc1..70e06d170d 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_houdini.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "houdini" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json index d8396b16cb..07c8aa0106 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_maya.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "maya" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json index af7cc3d301..bea59656af 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_mayabatch.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "mayabatch" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json index a8e3574aa3..6f67e29df2 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_photoshop.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "photoshop" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json index 052a935410..644e3046ce 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_resolve.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "resolve" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json index 3288fe2ffb..f2f9376029 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_shell.json @@ -13,8 +13,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "shell" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json index a3cc6188ac..fa28c4448c 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_tvpaint.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "tvpaint" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json index c79f08b71a..e9d1b68130 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/schema_unreal.json @@ -17,8 +17,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "unreal" + "type": "raw-json" }, { "type": "dict", diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json index c809891b30..cf43dca6b5 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json @@ -77,8 +77,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "{app_name}_{app_variant}" + "type": "raw-json" } ] } diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json index c86c2aef61..d99e0b9a85 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_nuke.json @@ -18,8 +18,7 @@ { "key": "environment", "label": "Environment", - "type": "raw-json", - "env_group_key": "{nuke_type}" + "type": "raw-json" }, { "type": "dict", From 6fa65a9bf8b26d544e6ab6c08d3ab1373f3fccff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:29:17 +0200 Subject: [PATCH 182/295] removed previous implementation of Application object --- pype/lib/applications.py | 88 ---------------------------------------- 1 file changed, 88 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 4b2cab99aa..a006538db1 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -235,94 +235,6 @@ class ApplicationExecutable: return bool(self._realpath()) -class Application: - """Hold information about application. - - Object by itself does nothing special. - - Args: - app_group (str): App group name. - e.g. "maya", "nuke", "photoshop", etc. - app_name (str): Specific version (or variant) of host. - e.g. "maya2020", "nuke11.3", etc. - host_name (str): Name of host implementation. - app_data (dict): Data for the version containing information about - executables, label, variant label, icon or if is enabled. - Only required key is `executables`. - manager (ApplicationManager): Application manager that created object. - """ - - def __init__(self, app_group, app_name, host_name, app_data, manager): - self.app_group = app_group - self.app_name = app_name - self.host_name = host_name - self.app_data = app_data - self.manager = manager - - self.label = app_data.get("label") or app_name - self.variant_label = app_data.get("variant_label") or None - self.icon = app_data.get("icon") or None - self.enabled = app_data.get("enabled", True) - self.is_host = app_data.get("is_host", False) - - _executables = app_data["executables"] - if not _executables: - _executables = [] - - elif isinstance(_executables, dict): - _executables = _executables.get(platform.system().lower()) or [] - - _arguments = app_data["arguments"] - if not _arguments: - _arguments = [] - - elif isinstance(_arguments, dict): - _arguments = _arguments.get(platform.system().lower()) or [] - - executables = [] - for executable in _executables: - executables.append(ApplicationExecutable(executable)) - - self.executables = executables - self.arguments = _arguments - - @property - def full_label(self): - """Full label of application. - - Concatenate `label` and `variant_label` attributes if `variant_label` - is set. - """ - if self.variant_label: - return "{} {}".format(self.label, self.variant_label) - return str(self.label) - - def find_executable(self): - """Try to find existing executable for application. - - Returns (str): Path to executable from `executables` or None if any - exists. - """ - for executable in self.executables: - if executable.exists(): - return executable - return None - - def launch(self, *args, **kwargs): - """Launch the application. - - For this purpose is used manager's launch method to keep logic at one - place. - - Arguments must match with manager's launch method. That's why *args - **kwargs are used. - - Returns: - subprocess.Popen: Return executed process as Popen object. - """ - return self.manager.launch(self.app_name, *args, **kwargs) - - @six.add_metaclass(ABCMeta) class LaunchHook: """Abstract base class of launch hook.""" From dcdbae5156efa4717814f040c58537b2b90734d1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:30:04 +0200 Subject: [PATCH 183/295] implemented application group class it's object holds environments --- pype/lib/applications.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index a006538db1..e2596cbacb 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -90,6 +90,37 @@ class ApplicationLaunchFailed(Exception): pass +class ApplicationGroup: + def __init__(self, name, data, manager): + self.name = name + self.manager = manager + self._data = data + + self.enabled = data.get("enabled", True) + self.label = data.get("label") or name + self.icon = data.get("icon") or None + self._environment = data.get("environment") or {} + + host_name = data.get("host_name", None) + self.is_host = host_name is not None + self.host_name = host_name + + variants = data.get("variants") or {} + + self.variants = variants + + def __repr__(self): + return "<{}> - {}".format(self.__class__.__name__, self.name) + + def __iter__(self): + for variant in self.variants.values(): + yield variant + + @property + def environment(self): + return copy.deepcopy(self._environment) + + class ApplicationManager: def __init__(self): self.log = PypeLogger().get_logger(self.__class__.__name__) From 68954e034e4edd24b060b84d938839cdf8a44d37 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:37:07 +0200 Subject: [PATCH 184/295] implemented new Application class which use more data from group and keeps only it's environments --- pype/lib/applications.py | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index e2596cbacb..3f573ba6c6 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -121,6 +121,81 @@ class ApplicationGroup: return copy.deepcopy(self._environment) +class Application: + """Hold information about application. + + Object by itself does nothing special. + + Args: + name (str): Specific version (or variant) of application. + e.g. "maya2020", "nuke11.3", etc. + data (dict): Data for the version containing information about + executables, variant label or if is enabled. + Only required key is `executables`. + group (ApplicationGroup): App group object that created the applicaiton + and under which application belongs. + """ + + def __init__(self, name, data, group): + self.name = name + self.group = group + self._data = data + + enabled = False + if group.enabled: + enabled = data.get("enabled", True) + self.enabled = enabled + + self.label = data.get("variant_label") or name + self.full_name = "/".join((group.name, name)) + self.full_label = " ".join((group.label, self.label)) + self._environment = data.get("environment") or {} + + _executables = data["executables"] + if not _executables: + _executables = [] + + elif isinstance(_executables, dict): + _executables = _executables.get(platform.system().lower()) or [] + + _arguments = data["arguments"] + if not _arguments: + _arguments = [] + + elif isinstance(_arguments, dict): + _arguments = _arguments.get(platform.system().lower()) or [] + + executables = [] + for executable in _executables: + executables.append(ApplicationExecutable(executable)) + + self.executables = executables + self.arguments = _arguments + + def __repr__(self): + return "<{}> - {}".format(self.__class__.__name__, self.full_name) + + @property + def environment(self): + return copy.deepcopy(self._environment) + + @property + def manager(self): + return self.group.manager + + @property + def host_name(self): + return self.group.host_name + + @property + def icon(self): + return self.group.icon + + @property + def is_host(self): + return self.group.is_host + + class ApplicationManager: def __init__(self): self.log = PypeLogger().get_logger(self.__class__.__name__) From be66e4cf70ad85df2b7aca47f5d3f9e950f1d3f3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:37:23 +0200 Subject: [PATCH 185/295] added docstring to ApplicationGroup --- pype/lib/applications.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 3f573ba6c6..efe8d5f73e 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -91,6 +91,22 @@ class ApplicationLaunchFailed(Exception): class ApplicationGroup: + """Hold information about application group. + + Application group wraps different versions(variants) of application. + e.g. "maya" is group and "maya_2020" is variant. + + Group hold `host_name` which is implementation name used in pype. Also + holds `enabled` if whole app group is enabled or `icon` for application + icon path in resources. + + Group has also `environment` which hold same environments for all variants. + + Args: + name (str): Groups' name. + data (dict): Group defying data loaded from settings. + manager (ApplicationManager): Manager that created the group. + """ def __init__(self, name, data, manager): self.name = name self.manager = manager From f5a046bbcbf07b2100faa9eda5de0331091f2086 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:37:43 +0200 Subject: [PATCH 186/295] ApplicationGroup creates objects of Application class --- pype/lib/applications.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index efe8d5f73e..77dc62f8c9 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -4,6 +4,7 @@ import copy import json import platform import getpass +import collections import inspect import subprocess import distutils.spawn @@ -122,6 +123,10 @@ class ApplicationGroup: self.host_name = host_name variants = data.get("variants") or {} + for variant_name, variant_data in variants.items(): + variants[variant_name] = Application( + variant_name, variant_data, self + ) self.variants = variants From aa0b3211fc4b27837beef7f1c08429168676b88a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:40:29 +0200 Subject: [PATCH 187/295] ApplicationManager is using new classes to get applications --- pype/lib/applications.py | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 77dc62f8c9..f53194ea72 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -221,6 +221,7 @@ class ApplicationManager: def __init__(self): self.log = PypeLogger().get_logger(self.__class__.__name__) + self.app_groups = {} self.applications = {} self.tools = {} @@ -228,42 +229,19 @@ class ApplicationManager: def refresh(self): """Refresh applications from settings.""" + self.app_groups.clear() self.applications.clear() self.tools.clear() settings = get_system_settings() - hosts_definitions = settings["applications"] - for app_group, variant_definitions in hosts_definitions.items(): - enabled = variant_definitions["enabled"] - label = variant_definitions.get("label") or app_group - variants = variant_definitions.get("variants") or {} - icon = variant_definitions.get("icon") - group_host_name = variant_definitions.get("host_name") or None - for app_name, app_data in variants.items(): - if app_name in self.applications: - raise AssertionError(( - "BUG: Duplicated application name in settings \"{}\"" - ).format(app_name)) - - # If host is disabled then disable all variants - if not enabled: - app_data["enabled"] = enabled - - # Pass label from host definition - if not app_data.get("label"): - app_data["label"] = label - - if not app_data.get("icon"): - app_data["icon"] = icon - - host_name = app_data.get("host_name") or group_host_name - - app_data["is_host"] = host_name is not None - - self.applications[app_name] = Application( - app_group, app_name, host_name, app_data, self - ) + app_defs = settings["applications"] + for group_name, variant_defs in app_defs.items(): + group = ApplicationGroup(group_name, variant_defs, self) + self.app_groups[group_name] = group + for app in group: + # TODO This should be replaced with `full_name` in future + self.applications[app.name] = app tools_definitions = settings["tools"]["tool_groups"] for tool_group_name, tool_group_data in tools_definitions.items(): From b6b1ab4b3a1257ca74c61c33276ee16fced6b29f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:40:43 +0200 Subject: [PATCH 188/295] reimplemented require Application methods --- pype/lib/applications.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index f53194ea72..161198a85d 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -216,6 +216,31 @@ class Application: def is_host(self): return self.group.is_host + def find_executable(self): + """Try to find existing executable for application. + + Returns (str): Path to executable from `executables` or None if any + exists. + """ + for executable in self.executables: + if executable.exists(): + return executable + return None + + def launch(self, *args, **kwargs): + """Launch the application. + + For this purpose is used manager's launch method to keep logic at one + place. + + Arguments must match with manager's launch method. That's why *args + **kwargs are used. + + Returns: + subprocess.Popen: Return executed process as Popen object. + """ + return self.manager.launch(self.name, *args, **kwargs) + class ApplicationManager: def __init__(self): From a507d78f9c19bf481333a0e85283ebabae0d362c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:43:05 +0200 Subject: [PATCH 189/295] fixed attributes usage --- pype/hooks/pre_global_host_data.py | 2 +- pype/lib/applications.py | 13 +++++++------ .../event_handlers_user/action_applications.py | 4 ++-- pype/tools/launcher/models.py | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/pype/hooks/pre_global_host_data.py b/pype/hooks/pre_global_host_data.py index 74be208367..876c5840e7 100644 --- a/pype/hooks/pre_global_host_data.py +++ b/pype/hooks/pre_global_host_data.py @@ -32,7 +32,7 @@ class GlobalHostDataHook(PreLaunchHook): "project_name": self.data["project_name"], "asset_name": self.data["asset_name"], "task_name": self.data["task_name"], - "app_name": app.app_name, + "app": app, "dbcon": self.data["dbcon"], diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 161198a85d..36d3722701 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -418,7 +418,7 @@ class LaunchHook: return False if cls.app_groups: - if launch_context.app_group not in cls.app_groups: + if launch_context.app_group.name not in cls.app_groups: return False if cls.app_names: @@ -445,11 +445,11 @@ class LaunchHook: @property def app_group(self): - return getattr(self.application, "app_group", None) + return getattr(self.application, "group", None) @property def app_name(self): - return getattr(self.application, "app_name", None) + return getattr(self.application, "name", None) def validate(self): """Optional validation of launch hook on initialization. @@ -718,7 +718,7 @@ class ApplicationLaunchContext: @property def app_name(self): - return self.application.app_name + return self.application.name @property def host_name(self): @@ -726,7 +726,7 @@ class ApplicationLaunchContext: @property def app_group(self): - return self.application.app_group + return self.application.group @property def manager(self): @@ -1060,7 +1060,8 @@ def prepare_context_environments(data): "AVALON_ASSET": asset_doc["name"], "AVALON_TASK": task_name, "AVALON_APP": app.host_name, - "AVALON_APP_NAME": app.app_name, + # TODO this hould be `app.full_name` in future PRs + "AVALON_APP_NAME": app.name, "AVALON_WORKDIR": workdir } log.debug( diff --git a/pype/modules/ftrack/event_handlers_user/action_applications.py b/pype/modules/ftrack/event_handlers_user/action_applications.py index 5b6657793a..2c42cadfb7 100644 --- a/pype/modules/ftrack/event_handlers_user/action_applications.py +++ b/pype/modules/ftrack/event_handlers_user/action_applications.py @@ -133,8 +133,8 @@ class AppplicationsAction(BaseAction): app_icon = None items.append({ - "label": app.label, - "variant": app.variant_label, + "label": app.group.label, + "variant": app.label, "description": None, "actionIdentifier": self.identifier + app_name, "icon": app_icon diff --git a/pype/tools/launcher/models.py b/pype/tools/launcher/models.py index d1742014ef..c617c7cace 100644 --- a/pype/tools/launcher/models.py +++ b/pype/tools/launcher/models.py @@ -162,9 +162,9 @@ class ActionModel(QtGui.QStandardItemModel): (ApplicationAction,), { "application": app, - "name": app.app_name, - "label": app.label, - "label_variant": app.variant_label, + "name": app.name, + "label": app.group.label, + "label_variant": app.label, "group": None, "icon": app.icon, "color": getattr(app, "color", None), From 9a18da32ac8ccab1cff76392e861c2208d8bf7ae Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:50:33 +0200 Subject: [PATCH 190/295] Implemented EnvironmentToolGroup to hold tool group --- pype/lib/applications.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 36d3722701..56432ec357 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -314,6 +314,46 @@ class ApplicationManager: return context.launch() +class EnvironmentToolGroup: + """Hold information about environment tool group. + + Environment tool group may hold different variants of same tool and set + environments that are same for all of them. + + e.g. "mtoa" may have different versions but all environments except one + are same. + + Args: + name (str): Name of the tool group. + data (dict): Group's information with it's variants. + manager (ApplicationManager): Manager that creates the group. + """ + + def __init__(self, name, data, manager): + self.name = name + self._data = data + self.manager = manager + self._environment = data["environment"] + + variants = data.get("variants") or {} + variants_by_name = {} + for variant_name, variant_env in variants.items(): + tool = EnvironmentTool(variant_name, variant_env, self) + variants_by_name[variant_name] = tool + self.variants = variants_by_name + + def __repr__(self): + return "<{}> - {}".format(self.__class__.__name__, self.name) + + def __iter__(self): + for variant in self.variants.values(): + yield variant + + @property + def environment(self): + return copy.deepcopy(self._environment) + + class ApplicationTool: """Hold information about application tool. From ed148c7c1135145d8b855e2f475e239d1de12c4a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:51:09 +0200 Subject: [PATCH 191/295] renamed ApplicationTool to EnvironmentTool and changed what data holds --- pype/lib/applications.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 56432ec357..5b0e61b909 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -354,23 +354,29 @@ class EnvironmentToolGroup: return copy.deepcopy(self._environment) -class ApplicationTool: +class EnvironmentTool: """Hold information about application tool. Structure of tool information. Args: - tool_name (str): Name of the tool. - group_name (str): Name of group which wraps tool. + name (str): Name of the tool. + environment (dict): Variant environments. + group (str): Name of group which wraps tool. """ - def __init__(self, tool_name, group_name): - self.name = tool_name - self.group_name = group_name + def __init__(self, name, environment, group): + self.name = name + self.group = group + self._environment = environment + self.full_name = "/".join((group.name, name)) + + def __repr__(self): + return "<{}> - {}".format(self.__class__.__name__, self.full_name) @property - def full_name(self): - return "/".join((self.group_name, self.name)) + def environment(self): + return copy.deepcopy(self._environment) class ApplicationExecutable: From 19313b06bdc2722eab88571921055cb6a357510b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:51:30 +0200 Subject: [PATCH 192/295] ApplicationManager use new tools classes to define it's tools --- pype/lib/applications.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 5b0e61b909..37021e0a5c 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -248,6 +248,7 @@ class ApplicationManager: self.app_groups = {} self.applications = {} + self.tool_groups = {} self.tools = {} self.refresh() @@ -256,6 +257,7 @@ class ApplicationManager: """Refresh applications from settings.""" self.app_groups.clear() self.applications.clear() + self.tool_groups.clear() self.tools.clear() settings = get_system_settings() @@ -270,13 +272,13 @@ class ApplicationManager: tools_definitions = settings["tools"]["tool_groups"] for tool_group_name, tool_group_data in tools_definitions.items(): - tool_variants = tool_group_data.get("variants") or {} - for tool_name, tool_data in tool_variants.items(): - tool = ApplicationTool(tool_name, tool_group_name) - if tool.full_name in self.tools: - self.log.warning(( - "Duplicated tool name in settings \"{}\"" - ).format(tool.full_name)) + if not tool_group_name: + continue + group = EnvironmentToolGroup( + tool_group_name, tool_group_data, self + ) + self.tool_groups[tool_group_name] = group + for tool in group: self.tools[tool.full_name] = tool def launch(self, app_name, **data): From 1a4abd712838ca1c3d80f9a3d00598a57748bc0f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:52:50 +0200 Subject: [PATCH 193/295] changed how environments for apps and tools are retrieved --- pype/lib/applications.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 37021e0a5c..cfb79f3a18 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -988,29 +988,42 @@ def prepare_host_environments(data): app = data["app"] log = data["log"] - # Keys for getting environments - env_keys = [app.app_group, app.app_name] + # `added_env_keys` has debug purpose + added_env_keys = {app.group.name, app.name} + # Environments for application + environments = [ + app.group.environment, + app.environment + ] asset_doc = data.get("asset_doc") + # Add tools environments + groups_by_name = {} + tool_by_group_name = collections.defaultdict(list) if asset_doc: - # Add tools environments + # Make sure each tool group can be added only once for key in asset_doc["data"].get("tools_env") or []: tool = app.manager.tools.get(key) - if tool: - if tool.group_name not in env_keys: - env_keys.append(tool.group_name) + if not tool: + continue + groups_by_name[tool.group.name] = tool.group + tool_by_group_name[tool.group.name].append(tool) - if tool.name not in env_keys: - env_keys.append(tool.name) + for group_name, group in groups_by_name.items(): + environments.append(group.environment) + added_env_keys.add(group_name) + for tool in tool_by_group_name[group_name]: + environments.append(tool.environment) + added_env_keys.add(tool.name) log.debug( - "Finding environment groups for keys: {}".format(env_keys) + "Will add environments for apps and tools: {}".format( + ", ".join(added_env_keys) + ) ) - settings_env = data["settings_env"] env_values = {} - for env_key in env_keys: - _env_values = settings_env.get(env_key) + for _env_values in environments: if not _env_values: continue From 9f14f89173260c47827d18f748f0671b9fdaaa07 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 19:53:47 +0200 Subject: [PATCH 194/295] removed usage of "settings_env" key in launch context --- pype/hooks/pre_global_host_data.py | 1 - pype/lib/applications.py | 9 --------- 2 files changed, 10 deletions(-) diff --git a/pype/hooks/pre_global_host_data.py b/pype/hooks/pre_global_host_data.py index 876c5840e7..5405bc0894 100644 --- a/pype/hooks/pre_global_host_data.py +++ b/pype/hooks/pre_global_host_data.py @@ -41,7 +41,6 @@ class GlobalHostDataHook(PreLaunchHook): "anatomy": self.data["anatomy"], - "settings_env": self.data.get("settings_env"), "env": self.launch_context.env, "log": self.log diff --git a/pype/lib/applications.py b/pype/lib/applications.py index cfb79f3a18..e7e161b0a9 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -572,12 +572,6 @@ class ApplicationLaunchContext: self.data = dict(data) - # Load settings if were not passed in data - settings_env = self.data.get("settings_env") - if settings_env is None: - settings_env = get_environments() - self.data["settings_env"] = settings_env - # subprocess.Popen launch arguments (first argument in constructor) self.launch_args = executable.as_args() self.launch_args.extend(application.arguments) @@ -896,9 +890,6 @@ class EnvironmentPrepData(dict): if data.get("env") is None: data["env"] = os.environ.copy() - if data.get("settings_env") is None: - data["settings_env"] = get_environments() - super(EnvironmentPrepData, self).__init__(data) From 0caa77261ac2ec30efe03fc9c75daccb747062b7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 20:02:20 +0200 Subject: [PATCH 195/295] removed label and icon from variants --- .../system_settings/applications.json | 88 ------------------- .../host_settings/template_host_variant.json | 14 --- 2 files changed, 102 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index 08e7a16599..5eccdfb83d 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -21,9 +21,7 @@ "variants": { "maya_2020": { "enabled": true, - "label": "", "variant_label": "2020", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2020\\bin\\maya.exe" @@ -44,9 +42,7 @@ }, "maya_2019": { "enabled": true, - "label": "", "variant_label": "2019", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2019\\bin\\maya.exe" @@ -67,9 +63,7 @@ }, "maya_2018": { "enabled": true, - "label": "", "variant_label": "2018", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2018\\bin\\maya.exe" @@ -113,9 +107,7 @@ "variants": { "mayabatch_2020": { "enabled": true, - "label": "", "variant_label": "2020", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2020\\bin\\mayabatch.exe" @@ -134,9 +126,7 @@ }, "mayabatch_2019": { "enabled": true, - "label": "", "variant_label": "2019", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2019\\bin\\mayabatch.exe" @@ -155,9 +145,7 @@ }, "mayabatch_2018": { "enabled": true, - "label": "", "variant_label": "2018", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Autodesk\\Maya2018\\bin\\mayabatch.exe" @@ -195,9 +183,7 @@ "variants": { "nuke_12-2": { "enabled": true, - "label": "", "variant_label": "12.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" @@ -216,9 +202,7 @@ }, "nuke_12-0": { "enabled": true, - "label": "", "variant_label": "12.0", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" @@ -237,9 +221,7 @@ }, "nuke_11-3": { "enabled": true, - "label": "", "variant_label": "11.3", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" @@ -258,9 +240,7 @@ }, "nuke_11-2": { "enabled": true, - "label": "", "variant_label": "11.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" @@ -296,9 +276,7 @@ "variants": { "nukex_12-2": { "enabled": true, - "label": "", "variant_label": "12.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" @@ -323,9 +301,7 @@ }, "nukex_12-0": { "enabled": true, - "label": "", "variant_label": "12.0", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" @@ -350,9 +326,7 @@ }, "nukex_11-3": { "enabled": true, - "label": "", "variant_label": "11.3", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" @@ -377,9 +351,7 @@ }, "nukex_11-2": { "enabled": true, - "label": "", "variant_label": "11.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" @@ -421,9 +393,7 @@ "variants": { "nukestudio_12-2": { "enabled": true, - "label": "", "variant_label": "12.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" @@ -448,9 +418,7 @@ }, "nukestudio_12-0": { "enabled": true, - "label": "", "variant_label": "12.0", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" @@ -475,9 +443,7 @@ }, "nukestudio_11-3": { "enabled": true, - "label": "", "variant_label": "11.3", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" @@ -502,9 +468,7 @@ }, "nukestudio_11-2": { "enabled": true, - "label": "", "variant_label": "11.2", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -544,9 +508,7 @@ "variants": { "hiero_12-2": { "enabled": true, - "label": "", "variant_label": "12.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe" @@ -571,9 +533,7 @@ }, "hiero_12-0": { "enabled": true, - "label": "", "variant_label": "12.0", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" @@ -598,9 +558,7 @@ }, "hiero_11-3": { "enabled": true, - "label": "", "variant_label": "11.3", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" @@ -625,9 +583,7 @@ }, "hiero_11-2": { "enabled": true, - "label": "", "variant_label": "11.2", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe" @@ -682,9 +638,7 @@ "variants": { "fusion_16": { "enabled": true, - "label": "", "variant_label": "16", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -699,9 +653,7 @@ }, "fusion_9": { "enabled": true, - "label": "", "variant_label": "9", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Blackmagic Design\\Fusion 9\\Fusion.exe" @@ -764,9 +716,7 @@ "variants": { "resolve_16": { "enabled": true, - "label": "", "variant_label": "16", - "icon": "", "executables": { "windows": [ "C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe" @@ -803,9 +753,7 @@ "variants": { "houdini_18-5": { "enabled": true, - "label": "", "variant_label": "18.5", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Side Effects Software\\Houdini 18.5.499\\bin\\houdini.exe" @@ -822,9 +770,7 @@ }, "houdini_18": { "enabled": true, - "label": "", "variant_label": "18", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -839,9 +785,7 @@ }, "houdini_17": { "enabled": true, - "label": "", "variant_label": "17", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -872,9 +816,7 @@ "variants": { "blender_2-83": { "enabled": true, - "label": "", "variant_label": "2.83", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Blender Foundation\\Blender 2.83\\blender.exe" @@ -897,9 +839,7 @@ }, "blender_2-90": { "enabled": true, - "label": "", "variant_label": "2.90", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" @@ -934,9 +874,7 @@ "variants": { "harmony_20": { "enabled": true, - "label": "", "variant_label": "20", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -951,9 +889,7 @@ }, "harmony_17": { "enabled": true, - "label": "", "variant_label": "17", - "icon": "", "executables": { "windows": [], "darwin": [ @@ -981,9 +917,7 @@ "variants": { "tvpaint_animation_11-64bits": { "enabled": true, - "label": "", "variant_label": "11 (64bits)", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 (64bits)\\TVPaint Animation 11 (64bits).exe" @@ -1000,9 +934,7 @@ }, "tvpaint_animation_11-32bits": { "enabled": true, - "label": "", "variant_label": "11 (32bits)", - "icon": "", "executables": { "windows": [ "C:\\Program Files (x86)\\TVPaint Developpement\\TVPaint Animation 11 (32bits)\\TVPaint Animation 11 (32bits).exe" @@ -1033,9 +965,7 @@ "variants": { "photoshop_2020": { "enabled": true, - "label": "", "variant_label": "2020", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Adobe\\Adobe Photoshop 2020\\Photoshop.exe" @@ -1052,9 +982,7 @@ }, "photoshop_2021": { "enabled": true, - "label": "", "variant_label": "2021", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Photoshop.exe" @@ -1085,9 +1013,7 @@ "variants": { "aftereffects_2020": { "enabled": true, - "label": "", "variant_label": "2020", - "icon": "", "executables": { "windows": [ "" @@ -1104,9 +1030,7 @@ }, "aftereffects_2021": { "enabled": true, - "label": "", "variant_label": "2021", - "icon": "", "executables": { "windows": [ "C:\\Program Files\\Adobe\\Adobe After Effects 2021\\Support Files\\AfterFX.exe" @@ -1134,9 +1058,7 @@ "variants": { "celation_Local": { "enabled": true, - "label": "", "variant_label": "Local", - "icon": "{}/app_icons/celaction_local.png", "executables": "", "arguments": { "windows": [], @@ -1160,9 +1082,7 @@ "variants": { "unreal_4-24": { "enabled": true, - "label": "", "variant_label": "4.24", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -1183,9 +1103,7 @@ "variants": { "python_python_3-7": { "enabled": true, - "label": "Python", "variant_label": "3.7", - "icon": "{}/app_icons/python.png", "executables": { "windows": [], "darwin": [], @@ -1200,9 +1118,7 @@ }, "python_python_2-7": { "enabled": true, - "label": "Python", "variant_label": "2.7", - "icon": "{}/app_icons/python.png", "executables": { "windows": [], "darwin": [], @@ -1217,9 +1133,7 @@ }, "terminal_terminal": { "enabled": true, - "label": "Terminal", "variant_label": "", - "icon": "", "executables": { "windows": [], "darwin": [], @@ -1243,9 +1157,7 @@ "variants": { "djvview_1-1": { "enabled": true, - "label": "", "variant_label": "1.1", - "icon": "", "executables": { "windows": [], "darwin": [], diff --git a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json index cf43dca6b5..10aab06466 100644 --- a/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json +++ b/pype/settings/entities/schemas/system_schema/host_settings/template_host_variant.json @@ -17,13 +17,6 @@ "key": "enabled", "label": "Enabled" }, - { - "type": "text", - "key": "label", - "label": "Label", - "placeholder": "Used from host label if not filled.", - "roles": ["developer"] - }, { "type": "text", "key": "variant_label", @@ -31,13 +24,6 @@ "placeholder": "Only \"Label\" is used if not filled.", "roles": ["developer"] }, - { - "type": "text", - "key": "icon", - "label": "Icon", - "placeholder": "Host icon path template. Used from host if not filled.", - "roles": ["developer"] - }, { "type": "path", "key": "executables", From f1b154a94f70527d7bd833137e0383747be5c762 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Tue, 30 Mar 2021 20:04:34 +0200 Subject: [PATCH 196/295] group does not have to have set label --- pype/lib/applications.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index e7e161b0a9..6df296db95 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -114,7 +114,7 @@ class ApplicationGroup: self._data = data self.enabled = data.get("enabled", True) - self.label = data.get("label") or name + self.label = data.get("label") or None self.icon = data.get("icon") or None self._environment = data.get("environment") or {} @@ -169,7 +169,12 @@ class Application: self.label = data.get("variant_label") or name self.full_name = "/".join((group.name, name)) - self.full_label = " ".join((group.label, self.label)) + + if group.label: + full_label = " ".join((group.label, self.label)) + else: + full_label = self.label + self.full_label = full_label self._environment = data.get("environment") or {} _executables = data["executables"] From 140457610e342c1753916a6e2e3bb5bd7a794005 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 10:51:25 +0200 Subject: [PATCH 197/295] removed SettingsFileHandler which is not and can't be used --- pype/settings/handlers.py | 177 -------------------------------------- 1 file changed, 177 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 6e93f2f405..fa8a97869b 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -126,183 +126,6 @@ class LocalSettingsHandler: pass -class SettingsFileHandler(SettingsHandler): - def __init__(self): - self.log = logging.getLogger("SettingsFileHandler") - - # Folder where studio overrides are stored - studio_overrides_dir = os.getenv("PYPE_PROJECT_CONFIGS") - if not studio_overrides_dir: - studio_overrides_dir = os.path.dirname(os.path.dirname( - os.path.abspath(pype.__file__) - )) - system_settings_path = os.path.join( - studio_overrides_dir, SYSTEM_SETTINGS_KEY + ".json" - ) - - # File where studio's default project overrides are stored - project_settings_filename = PROJECT_SETTINGS_KEY + ".json" - project_settings_path = os.path.join( - studio_overrides_dir, project_settings_filename - ) - - project_anatomy_filename = PROJECT_ANATOMY_KEY + ".json" - project_anatomy_path = os.path.join( - studio_overrides_dir, project_anatomy_filename - ) - - self.studio_overrides_dir = studio_overrides_dir - self.system_settings_path = system_settings_path - - self.project_settings_filename = project_settings_filename - self.project_anatomy_filename = project_anatomy_filename - - self.project_settings_path = project_settings_path - self.project_anatomy_path = project_anatomy_path - - def path_to_project_settings(self, project_name): - if not project_name: - return self.project_settings_path - return os.path.join( - self.studio_overrides_dir, - project_name, - self.project_settings_filename - ) - - def path_to_project_anatomy(self, project_name): - if not project_name: - return self.project_anatomy_path - return os.path.join( - self.studio_overrides_dir, - project_name, - self.project_anatomy_filename - ) - - def save_studio_settings(self, data): - """Save studio overrides of system settings. - - Do not use to store whole system settings data with defaults but only - it's overrides with metadata defining how overrides should be applied - in load function. For loading should be used function - `studio_system_settings`. - - Args: - data(dict): Data of studio overrides with override metadata. - """ - dirpath = os.path.dirname(self.system_settings_path) - if not os.path.exists(dirpath): - os.makedirs(dirpath) - - self.log.debug( - "Saving studio overrides. Output path: {}".format( - self.system_settings_path - ) - ) - with open(self.system_settings_path, "w") as file_stream: - json.dump(data, file_stream, indent=4) - - def save_project_settings(self, project_name, overrides): - """Save studio overrides of project settings. - - Data are saved for specific project or as defaults for all projects. - - Do not use to store whole project settings data with defaults but only - it's overrides with metadata defining how overrides should be applied - in load function. For loading should be used function - `get_studio_project_settings_overrides` for global project settings - and `get_project_settings_overrides` for project specific settings. - - Args: - project_name(str, null): Project name for which overrides are - or None for global settings. - data(dict): Data of project overrides with override metadata. - """ - project_overrides_json_path = self.path_to_project_settings( - project_name - ) - dirpath = os.path.dirname(project_overrides_json_path) - if not os.path.exists(dirpath): - os.makedirs(dirpath) - - self.log.debug( - "Saving overrides of project \"{}\". Output path: {}".format( - project_name, project_overrides_json_path - ) - ) - with open(project_overrides_json_path, "w") as file_stream: - json.dump(overrides, file_stream, indent=4) - - def save_project_anatomy(self, project_name, anatomy_data): - """Save studio overrides of project anatomy data. - - Args: - project_name(str, null): Project name for which overrides are - or None for global settings. - data(dict): Data of project overrides with override metadata. - """ - project_anatomy_json_path = self.path_to_project_anatomy(project_name) - dirpath = os.path.dirname(project_anatomy_json_path) - if not os.path.exists(dirpath): - os.makedirs(dirpath) - - self.log.debug( - "Saving anatomy of project \"{}\". Output path: {}".format( - project_name, project_anatomy_json_path - ) - ) - with open(project_anatomy_json_path, "w") as file_stream: - json.dump(anatomy_data, file_stream, indent=4) - - def get_studio_system_settings_overrides(self): - """Studio overrides of system settings.""" - if os.path.exists(self.system_settings_path): - return load_json_file(self.system_settings_path) - return {} - - def get_studio_project_settings_overrides(self): - """Studio overrides of default project settings.""" - if os.path.exists(self.project_settings_path): - return load_json_file(self.project_settings_path) - return {} - - def get_studio_project_anatomy_overrides(self): - """Studio overrides of default project anatomy data.""" - if os.path.exists(self.project_anatomy_path): - return load_json_file(self.project_anatomy_path) - return {} - - def get_project_settings_overrides(self, project_name): - """Studio overrides of project settings for specific project. - - Args: - project_name(str): Name of project for which data should be loaded. - - Returns: - dict: Only overrides for entered project, may be empty dictionary. - """ - path_to_json = self.path_to_project_settings(project_name) - if not os.path.exists(path_to_json): - return {} - return load_json_file(path_to_json) - - def get_project_anatomy_overrides(self, project_name): - """Studio overrides of project anatomy for specific project. - - Args: - project_name(str): Name of project for which data should be loaded. - - Returns: - dict: Only overrides for entered project, may be empty dictionary. - """ - if not project_name: - return {} - - path_to_json = self.path_to_project_anatomy(project_name) - if not os.path.exists(path_to_json): - return {} - return load_json_file(path_to_json) - - class CacheValues: cache_lifetime = 10 From 6221b6aa1e782416a86f3f6f9d8749380552d76a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 11:02:32 +0200 Subject: [PATCH 198/295] hide expainding button if content layout does not have any widget --- pype/tools/settings/settings/widgets/item_widgets.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_widgets.py b/pype/tools/settings/settings/widgets/item_widgets.py index e2e31a7588..6045b05227 100644 --- a/pype/tools/settings/settings/widgets/item_widgets.py +++ b/pype/tools/settings/settings/widgets/item_widgets.py @@ -59,6 +59,9 @@ class DictImmutableKeysWidget(BaseWidget): ) ) + if self.entity.use_label_wrap and self.content_layout.count() == 0: + self.body_widget.hide_toolbox(True) + self.entity_widget.add_widget_to_layout(self, label) def _prepare_entity_layouts(self, children, widget): From 56c4ae7eb7b81b400693a75d277a0c1609fe5aa6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 14:57:36 +0200 Subject: [PATCH 199/295] removed studio soft key from general and replaced with pype_path key --- .../schemas/system_schema/schema_general.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pype/settings/entities/schemas/system_schema/schema_general.json b/pype/settings/entities/schemas/system_schema/schema_general.json index cf88043cd0..26dc251acf 100644 --- a/pype/settings/entities/schemas/system_schema/schema_general.json +++ b/pype/settings/entities/schemas/system_schema/schema_general.json @@ -19,20 +19,20 @@ "type": "splitter" }, { - "key": "studio_soft", - "type": "path", - "label": "Studio Software Location", - "multiplatform": true, - "multipath": false + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "global" }, { "type": "splitter" }, { - "key": "environment", - "label": "Environment", - "type": "raw-json", - "env_group_key": "global" + "type": "path", + "key": "pype_path", + "label": "Pype Path", + "multiplatform": true, + "multipath": true } ] } From 85863015a38cfa6218d094c5c30fa3122878f085 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 14:57:51 +0200 Subject: [PATCH 200/295] defined constant for global settings type --- pype/settings/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/settings/constants.py b/pype/settings/constants.py index f6077e826e..a53e88a91e 100644 --- a/pype/settings/constants.py +++ b/pype/settings/constants.py @@ -15,6 +15,7 @@ METADATA_KEYS = ( ) # File where studio's system overrides are stored +GLOBAL_SETTINGS_KEY = "global_settings" SYSTEM_SETTINGS_KEY = "system_settings" PROJECT_SETTINGS_KEY = "project_settings" PROJECT_ANATOMY_KEY = "project_anatomy" From 969b2dedef573575c00eb408541b7d3232783835 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 14:58:19 +0200 Subject: [PATCH 201/295] resaved defaults --- pype/settings/defaults/system_settings/general.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/settings/defaults/system_settings/general.json b/pype/settings/defaults/system_settings/general.json index e03e00aca8..99db4e85c6 100644 --- a/pype/settings/defaults/system_settings/general.json +++ b/pype/settings/defaults/system_settings/general.json @@ -1,11 +1,6 @@ { "studio_name": "Studio name", "studio_code": "stu", - "studio_soft": { - "windows": "convert from \"STUDIO_SOFT\"", - "darwin": "", - "linux": "" - }, "environment": { "FFMPEG_PATH": { "windows": "{PYPE_ROOT}/vendor/bin/ffmpeg_exec/windows/bin", @@ -19,5 +14,10 @@ "PYPE_OCIO_CONFIG" ] } + }, + "pype_path": { + "windows": [], + "darwin": [], + "linux": [] } } \ No newline at end of file From cd9254b27d897fdf97313cb126528a958a819c84 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 14:58:50 +0200 Subject: [PATCH 202/295] settings handler saves pype_path from system settings to global settings on save --- pype/settings/handlers.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 5a4e507547..0891ac39b5 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -8,6 +8,7 @@ from abc import ABCMeta, abstractmethod import six import pype from .constants import ( + GLOBAL_SETTINGS_KEY, SYSTEM_SETTINGS_KEY, PROJECT_SETTINGS_KEY, PROJECT_ANATOMY_KEY, @@ -401,6 +402,11 @@ class MongoSettingsHandler(SettingsHandler): self._prepare_project_settings_keys() return self._attribute_keys + def _prepare_global_settings(self, data): + if "general" not in data: + return {} + return data["general"].get("pype_path") or {} + def save_studio_settings(self, data): """Save studio overrides of system settings. @@ -412,8 +418,8 @@ class MongoSettingsHandler(SettingsHandler): Args: data(dict): Data of studio overrides with override metadata. """ + # Store system settings self.system_settings_cache.update_data(data) - self.collection.replace_one( { "type": SYSTEM_SETTINGS_KEY @@ -425,6 +431,22 @@ class MongoSettingsHandler(SettingsHandler): upsert=True ) + # Get global settings from system settings + global_settings = self._prepare_global_settings( + self.system_settings_cache.data + ) + # Store global settings + self.collection.replace_one( + { + "type": GLOBAL_SETTINGS_KEY + }, + { + "type": GLOBAL_SETTINGS_KEY, + "data": global_settings + }, + upsert=True + ) + def save_project_settings(self, project_name, overrides): """Save studio overrides of project settings. From a9442274ec4c533f8fd4aac1e672d0063ed33e70 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 14:59:23 +0200 Subject: [PATCH 203/295] removed unused function load_environments from igniter --- igniter/tools.py | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/igniter/tools.py b/igniter/tools.py index 4ed4ae67f4..43cea8382a 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -185,38 +185,6 @@ def validate_path_string(path: str) -> (bool, str): return True, "valid path" -def load_environments(sections: list = None) -> dict: - """Load environments from Pype. - - This will load environments from database, process them with - :mod:`acre` and return them as flattened dictionary. - - Args: - sections (list, optional): load specific types - - Returns; - dict of str: loaded and processed environments. - - """ - import acre - - from pype import settings - - all_env = settings.get_environments() - merged_env = {} - - sections = sections or all_env.keys() - - for section in sections: - try: - parsed_env = acre.parse(all_env[section]) - except AttributeError: - continue - merged_env = acre.append(merged_env, parsed_env) - - return acre.compute(merged_env, cleanup=True) - - def get_pype_path_from_db(url: str) -> Union[str, None]: """Get Pype path from database. From e7781a454003481b59191a3093c4036532c3192c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:00:41 +0200 Subject: [PATCH 204/295] added function to load global settings from mongo --- igniter/tools.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/igniter/tools.py b/igniter/tools.py index 43cea8382a..4d82783607 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -185,6 +185,44 @@ def validate_path_string(path: str) -> (bool, str): return True, "valid path" +def get_pype_global_settings(url: str) -> dict: + """Load global settings from Mongo database. + + We are loading data from database `pype` and collection `settings`. + There we expect document type `global_settings`. + + Returns: + dict: With settings data. Empty dictionary is returned if not found. + """ + try: + components = decompose_url(url) + except RuntimeError: + return {} + mongo_kwargs = { + "host": compose_url(**components), + "serverSelectionTimeoutMS": 2000 + } + port = components.get("port") + if port is not None: + mongo_kwargs["port"] = int(port) + + try: + # Create mongo connection + client = MongoClient(**mongo_kwargs) + # Access settings collection + col = client["pype"]["settings"] + # Query global settings + global_settings = col.find_one({"type": "global_settings"}) or {} + # Close Mongo connection + client.close() + + except Exception: + # TODO log traceback or message + return {} + + return global_settings.get("data") or {} + + def get_pype_path_from_db(url: str) -> Union[str, None]: """Get Pype path from database. From b98fd5d0a9c2f281821d8ade50a3ad4c4ff082c9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:02:18 +0200 Subject: [PATCH 205/295] modified `get_pype_path_from_db` to use `get_pype_global_settings` function --- igniter/tools.py | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/igniter/tools.py b/igniter/tools.py index 4d82783607..80fcd5a9e6 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -224,40 +224,13 @@ def get_pype_global_settings(url: str) -> dict: def get_pype_path_from_db(url: str) -> Union[str, None]: - """Get Pype path from database. - - We are loading data from database `pype` and collection `settings`. - There we expect document type `global_settings`. + """Get Pype path from global settings. Args: url (str): mongodb url. Returns: path to Pype or None if not found - """ - try: - components = decompose_url(url) - except RuntimeError: - return None - mongo_args = { - "host": compose_url(**components), - "serverSelectionTimeoutMS": 2000 - } - port = components.get("port") - if port is not None: - mongo_args["port"] = int(port) - - try: - client = MongoClient(**mongo_args) - except Exception: - return None - - db = client.pype - col = db.settings - - global_settings = col.find_one({"type": "global_settings"}, {"data": 1}) - if not global_settings: - return None - global_settings.get("data", {}) + global_settings = get_pype_global_settings(url) return global_settings.get("pype_path", {}).get(platform.system().lower()) From c51f31161eea1a664912dfe0f4f8dc384a471a5a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:07:20 +0200 Subject: [PATCH 206/295] changed how paths are checked --- igniter/tools.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/igniter/tools.py b/igniter/tools.py index 80fcd5a9e6..7f5aa8d876 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -6,6 +6,7 @@ Functions ``compose_url()`` and ``decompose_url()`` are the same as in version is decided. """ +import os from typing import Dict, Union from urllib.parse import urlparse, parse_qs from pathlib import Path @@ -234,3 +235,17 @@ def get_pype_path_from_db(url: str) -> Union[str, None]: """ global_settings = get_pype_global_settings(url) return global_settings.get("pype_path", {}).get(platform.system().lower()) + paths = ( + global_settings + .get("pype_path", {}) + .get(platform.system().lower()) + ) or [] + # For cases when `pype_path` is a single path + if paths and isinstance(paths, str): + paths = [paths] + + # Loop over paths and return only existing + for path in paths: + if os.path.exists(path): + return path + return None From 4eab3340a16a7719d0719c4827745ab5e00f6d29 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:07:39 +0200 Subject: [PATCH 207/295] fix label issue --- pype/settings/entities/enum_entity.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pype/settings/entities/enum_entity.py b/pype/settings/entities/enum_entity.py index c486de397e..e28fb7478f 100644 --- a/pype/settings/entities/enum_entity.py +++ b/pype/settings/entities/enum_entity.py @@ -133,12 +133,9 @@ class AppsEnumEntity(BaseEnumEntity): if enabled_entity and not enabled_entity.value: continue - _group_label = variant_entity["label"].value - if not _group_label: - _group_label = group_label variant_label = variant_entity["variant_label"].value - full_label = "{} {}".format(_group_label, variant_label) + full_label = "{} {}".format(group_label, variant_label) enum_items.append({variant_name: full_label}) valid_keys.add(variant_name) return enum_items, valid_keys From 75f9fd7d1c8845cffe30e5aef01a795d73b5b4cd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:26:44 +0200 Subject: [PATCH 208/295] close validation mongo connection --- igniter/tools.py | 1 + 1 file changed, 1 insertion(+) diff --git a/igniter/tools.py b/igniter/tools.py index 7f5aa8d876..38d7fa2b26 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -131,6 +131,7 @@ def validate_mongo_connection(cnx: str) -> (bool, str): try: client = MongoClient(**mongo_args) client.server_info() + client.close() except ServerSelectionTimeoutError as e: return False, f"Cannot connect to server {cnx} - {e}" except ValueError: From 86755f97cc54dca0c4a94781f311ad13ea3a4c0c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 15:46:05 +0200 Subject: [PATCH 209/295] fix global settings dict hierarchy --- pype/settings/handlers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pype/settings/handlers.py b/pype/settings/handlers.py index 0891ac39b5..cc071f9fb5 100644 --- a/pype/settings/handlers.py +++ b/pype/settings/handlers.py @@ -403,9 +403,11 @@ class MongoSettingsHandler(SettingsHandler): return self._attribute_keys def _prepare_global_settings(self, data): - if "general" not in data: - return {} - return data["general"].get("pype_path") or {} + output = {} + # Add "pype_path" key to global settings if is set + if "general" in data and "pype_path" in data["general"]: + output["pype_path"] = data["general"]["pype_path"] + return output def save_studio_settings(self, data): """Save studio overrides of system settings. From fae5a6506ce294ce6b2b251bf70c9e6d6582b1cd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 16:16:44 +0200 Subject: [PATCH 210/295] added `url` argument back to docstring --- igniter/tools.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/igniter/tools.py b/igniter/tools.py index 38d7fa2b26..08157e8728 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -193,6 +193,9 @@ def get_pype_global_settings(url: str) -> dict: We are loading data from database `pype` and collection `settings`. There we expect document type `global_settings`. + Args: + url (str): MongoDB url. + Returns: dict: With settings data. Empty dictionary is returned if not found. """ From 3280d1a8aadde67a10817531cb2471cf530ef0eb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 16:16:54 +0200 Subject: [PATCH 211/295] removed forgotten line --- igniter/tools.py | 1 - 1 file changed, 1 deletion(-) diff --git a/igniter/tools.py b/igniter/tools.py index 08157e8728..11fe6b02f2 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -238,7 +238,6 @@ def get_pype_path_from_db(url: str) -> Union[str, None]: path to Pype or None if not found """ global_settings = get_pype_global_settings(url) - return global_settings.get("pype_path", {}).get(platform.system().lower()) paths = ( global_settings .get("pype_path", {}) From fc103ec5c31dcbb83b874da207b3deb9de437c05 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 19:49:46 +0200 Subject: [PATCH 212/295] auto create new item on getitem in mutable dict --- pype/settings/entities/dict_mutable_keys_entity.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/settings/entities/dict_mutable_keys_entity.py b/pype/settings/entities/dict_mutable_keys_entity.py index b465171734..d4bf208555 100644 --- a/pype/settings/entities/dict_mutable_keys_entity.py +++ b/pype/settings/entities/dict_mutable_keys_entity.py @@ -44,6 +44,8 @@ class DictMutableKeysEntity(EndpointEntity): _miss_arg = object() def __getitem__(self, key): + if key not in self.children_by_key: + self.add_key(key) return self.children_by_key[key] def __setitem__(self, key, value): From 9bb1d87304a3a9f094c1304af23a344ccb94938f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Wed, 31 Mar 2021 19:50:06 +0200 Subject: [PATCH 213/295] added sequence tag to extract review profiles --- .../projects_schema/schemas/schema_global_publish.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index b4d1876297..3c079a130d 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -119,7 +119,10 @@ "slate-frame": "Add slate frame" }, { - "no-hnadles": "Skip handle frames" + "no-handles": "Skip handle frames" + }, + { + "sequence": "Output as image sequence" } ] }, From 2d86b54841593521f6dfa7a7655aae7093d11784 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 10:40:10 +0200 Subject: [PATCH 214/295] renamed `pype` in schemas to `openpype` --- schema/application-1.0.json | 2 +- schema/asset-1.0.json | 4 ++-- schema/asset-2.0.json | 6 +++--- schema/asset-3.0.json | 6 +++--- schema/config-1.0.json | 2 +- schema/config-1.1.json | 2 +- schema/config-2.0.json | 2 +- schema/container-1.0.json | 2 +- schema/container-2.0.json | 8 ++++---- schema/hero_version-1.0.json | 6 +++--- schema/inventory-1.0.json | 2 +- schema/inventory-1.1.json | 2 +- schema/project-2.0.json | 8 ++++---- schema/project-2.1.json | 8 ++++---- schema/project-3.0.json | 6 +++--- schema/representation-1.0.json | 2 +- schema/representation-2.0.json | 6 +++--- schema/session-1.0.json | 4 ++-- schema/session-2.0.json | 2 +- schema/shaders-1.0.json | 2 +- schema/subset-1.0.json | 4 ++-- schema/subset-2.0.json | 6 +++--- schema/subset-3.0.json | 8 ++++---- schema/thumbnail-1.0.json | 6 +++--- schema/version-1.0.json | 2 +- schema/version-2.0.json | 10 +++++----- schema/version-3.0.json | 8 ++++---- schema/workfile-1.0.json | 6 +++--- 28 files changed, 66 insertions(+), 66 deletions(-) diff --git a/schema/application-1.0.json b/schema/application-1.0.json index e2418037c6..953abee569 100644 --- a/schema/application-1.0.json +++ b/schema/application-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:application-1.0", + "title": "openpype:application-1.0", "description": "An application definition.", "type": "object", diff --git a/schema/asset-1.0.json b/schema/asset-1.0.json index 6f3665c628..ab104c002a 100644 --- a/schema/asset-1.0.json +++ b/schema/asset-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:asset-1.0", + "title": "openpype:asset-1.0", "description": "A unit of data", "type": "object", @@ -32,4 +32,4 @@ }, "definitions": {} -} \ No newline at end of file +} diff --git a/schema/asset-2.0.json b/schema/asset-2.0.json index 066cb33498..b894d79792 100644 --- a/schema/asset-2.0.json +++ b/schema/asset-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:asset-2.0", + "title": "openpype:asset-2.0", "description": "A unit of data", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:asset-2.0"], - "example": "avalon-core:asset-2.0" + "enum": ["openpype:asset-2.0"], + "example": "openpype:asset-2.0" }, "type": { "description": "The type of document", diff --git a/schema/asset-3.0.json b/schema/asset-3.0.json index a3a22e917b..948704d2a1 100644 --- a/schema/asset-3.0.json +++ b/schema/asset-3.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:asset-3.0", + "title": "openpype:asset-3.0", "description": "A unit of data", "type": "object", @@ -19,8 +19,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:asset-3.0", "pype:asset-3.0"], - "example": "avalon-core:asset-3.0" + "enum": ["openpype:asset-3.0"], + "example": "openpype:asset-3.0" }, "type": { "description": "The type of document", diff --git a/schema/config-1.0.json b/schema/config-1.0.json index 198f51e04d..49398a57cd 100644 --- a/schema/config-1.0.json +++ b/schema/config-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:config-1.0", + "title": "openpype:config-1.0", "description": "A project configuration.", "type": "object", diff --git a/schema/config-1.1.json b/schema/config-1.1.json index ea5ab0ff27..6e15514aaf 100644 --- a/schema/config-1.1.json +++ b/schema/config-1.1.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:config-1.1", + "title": "openpype:config-1.1", "description": "A project configuration.", "type": "object", diff --git a/schema/config-2.0.json b/schema/config-2.0.json index 098d1983e2..54b226711a 100644 --- a/schema/config-2.0.json +++ b/schema/config-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:config-2.0", + "title": "openpype:config-2.0", "description": "A project configuration.", "type": "object", diff --git a/schema/container-1.0.json b/schema/container-1.0.json index d9e4e39f7f..012e8499e6 100644 --- a/schema/container-1.0.json +++ b/schema/container-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:container-1.0", + "title": "openpype:container-1.0", "description": "A loaded asset", "type": "object", diff --git a/schema/container-2.0.json b/schema/container-2.0.json index 7b84209ea0..1673ee5d1d 100644 --- a/schema/container-2.0.json +++ b/schema/container-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:container-2.0", + "title": "openpype:container-2.0", "description": "A loaded asset", "type": "object", @@ -21,8 +21,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:container-2.0", "pype:container-2.0"], - "example": "pype:container-2.0" + "enum": ["openpype:container-2.0"], + "example": "openpype:container-2.0" }, "id": { "description": "Identifier for finding object in host", @@ -56,4 +56,4 @@ "example": "59523f355f8c1b5f6c5e8348" } } -} \ No newline at end of file +} diff --git a/schema/hero_version-1.0.json b/schema/hero_version-1.0.json index 83304ef4d5..b720dc2887 100644 --- a/schema/hero_version-1.0.json +++ b/schema/hero_version-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:hero_version-1.0", + "title": "openpype:hero_version-1.0", "description": "Hero version of asset", "type": "object", @@ -27,8 +27,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["avalon-core:hero_version-1.0", "pype:hero_version-1.0"], - "example": "pype:hero_version-1.0" + "enum": ["openpype:hero_version-1.0"], + "example": "openpype:hero_version-1.0" }, "type": { "description": "The type of document", diff --git a/schema/inventory-1.0.json b/schema/inventory-1.0.json index 888ba7945a..2fe78794ab 100644 --- a/schema/inventory-1.0.json +++ b/schema/inventory-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:config-1.0", + "title": "openpype:config-1.0", "description": "A project configuration.", "type": "object", diff --git a/schema/inventory-1.1.json b/schema/inventory-1.1.json index 1b572b7d23..b61a76b32a 100644 --- a/schema/inventory-1.1.json +++ b/schema/inventory-1.1.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:config-1.1", + "title": "openpype:config-1.1", "description": "A project configuration.", "type": "object", diff --git a/schema/project-2.0.json b/schema/project-2.0.json index ad0e460f4d..0ed5a55599 100644 --- a/schema/project-2.0.json +++ b/schema/project-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:project-2.0", + "title": "openpype:project-2.0", "description": "A unit of data", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:project-2.0", "pype:project-2.0"], - "example": "avalon-core:project-2.0" + "enum": ["openpype:project-2.0"], + "example": "openpype:project-2.0" }, "type": { "description": "The type of document", @@ -52,7 +52,7 @@ "type": "object", "description": "Document metadata", "example": { - "schema": "pype:config-1.0", + "schema": "openpype:config-1.0", "apps": [ { "name": "maya2016", diff --git a/schema/project-2.1.json b/schema/project-2.1.json index 40e3bdb638..9413c9f691 100644 --- a/schema/project-2.1.json +++ b/schema/project-2.1.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:project-2.1", + "title": "openpype:project-2.1", "description": "A unit of data", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:project-2.1", "pype:project-2.1"], - "example": "avalon-core:project-2.1" + "enum": ["openpype:project-2.1"], + "example": "openpype:project-2.1" }, "type": { "description": "The type of document", @@ -52,7 +52,7 @@ "type": "object", "description": "Document metadata", "example": { - "schema": "pype:config-1.1", + "schema": "openpype:config-1.1", "apps": [ { "name": "maya2016", diff --git a/schema/project-3.0.json b/schema/project-3.0.json index d6368d665c..be23e10c93 100644 --- a/schema/project-3.0.json +++ b/schema/project-3.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:project-3.0", + "title": "openpype:project-3.0", "description": "A unit of data", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["pype:project-3.0"], - "example": "pype:project-3.0" + "enum": ["openpype:project-3.0"], + "example": "openpype:project-3.0" }, "type": { "description": "The type of document", diff --git a/schema/representation-1.0.json b/schema/representation-1.0.json index 10ae72928e..347c585f52 100644 --- a/schema/representation-1.0.json +++ b/schema/representation-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:representation-1.0", + "title": "openpype:representation-1.0", "description": "The inverse of an instance", "type": "object", diff --git a/schema/representation-2.0.json b/schema/representation-2.0.json index e12dea8564..f47c16a10a 100644 --- a/schema/representation-2.0.json +++ b/schema/representation-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:representation-2.0", + "title": "openpype:representation-2.0", "description": "The inverse of an instance", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["avalon-core:representation-2.0", "pype:representation-2.0"], - "example": "pype:representation-2.0" + "enum": ["openpype:representation-2.0"], + "example": "openpype:representation-2.0" }, "type": { "description": "The type of document", diff --git a/schema/session-1.0.json b/schema/session-1.0.json index 2b201f9c61..5ced0a6f08 100644 --- a/schema/session-1.0.json +++ b/schema/session-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:session-1.0", + "title": "openpype:session-1.0", "description": "The Avalon environment", "type": "object", @@ -140,4 +140,4 @@ "example": "True" } } -} \ No newline at end of file +} diff --git a/schema/session-2.0.json b/schema/session-2.0.json index 7ad2c63bcf..0a4d51beb2 100644 --- a/schema/session-2.0.json +++ b/schema/session-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:session-2.0", + "title": "openpype:session-2.0", "description": "The Avalon environment", "type": "object", diff --git a/schema/shaders-1.0.json b/schema/shaders-1.0.json index e66cc735e8..7102ba1861 100644 --- a/schema/shaders-1.0.json +++ b/schema/shaders-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:shaders-1.0", + "title": "openpype:shaders-1.0", "description": "Relationships between shaders and Avalon IDs", "type": "object", diff --git a/schema/subset-1.0.json b/schema/subset-1.0.json index 90ae0349fa..a299a6d341 100644 --- a/schema/subset-1.0.json +++ b/schema/subset-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:subset-1.0", + "title": "openpype:subset-1.0", "description": "A container of instances", "type": "object", @@ -32,4 +32,4 @@ }, "definitions": {} -} \ No newline at end of file +} diff --git a/schema/subset-2.0.json b/schema/subset-2.0.json index 98f39c4f3e..db256ec7fb 100644 --- a/schema/subset-2.0.json +++ b/schema/subset-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:subset-2.0", + "title": "openpype:subset-2.0", "description": "A container of instances", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["pype:subset-2.0"], - "example": "pype:subset-2.0" + "enum": ["openpype:subset-2.0"], + "example": "openpype:subset-2.0" }, "type": { "description": "The type of document", diff --git a/schema/subset-3.0.json b/schema/subset-3.0.json index a0af9d340f..1a0db53c04 100644 --- a/schema/subset-3.0.json +++ b/schema/subset-3.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:subset-3.0", + "title": "openpype:subset-3.0", "description": "A container of instances", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["avalon-core:subset-3.0", "pype:subset-3.0"], - "example": "pype:subset-3.0" + "enum": ["openpype:subset-3.0"], + "example": "openpype:subset-3.0" }, "type": { "description": "The type of document", @@ -51,7 +51,7 @@ } }, "example": { - "families" : [ + "families" : [ "avalon.camera" ], "frameStart": 1000, diff --git a/schema/thumbnail-1.0.json b/schema/thumbnail-1.0.json index 96b540ab7e..5bdf78a4b1 100644 --- a/schema/thumbnail-1.0.json +++ b/schema/thumbnail-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:thumbnail-1.0", + "title": "openpype:thumbnail-1.0", "description": "Entity with thumbnail data", "type": "object", @@ -18,8 +18,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["pype:thumbnail-1.0"], - "example": "pype:thumbnail-1.0" + "enum": ["openpype:thumbnail-1.0"], + "example": "openpype:thumbnail-1.0" }, "type": { "description": "The type of document", diff --git a/schema/version-1.0.json b/schema/version-1.0.json index c784a25175..daa1997721 100644 --- a/schema/version-1.0.json +++ b/schema/version-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:version-1.0", + "title": "openpype:version-1.0", "description": "An individual version", "type": "object", diff --git a/schema/version-2.0.json b/schema/version-2.0.json index 5bb4a56f96..099e9be70a 100644 --- a/schema/version-2.0.json +++ b/schema/version-2.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:version-2.0", + "title": "openpype:version-2.0", "description": "An individual version", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["pype:version-2.0"], - "example": "pype:version-2.0" + "enum": ["openpype:version-2.0"], + "example": "openpype:version-2.0" }, "type": { "description": "The type of document", @@ -82,10 +82,10 @@ "example": { "source" : "{root}/f02_prod/assets/BubbleWitch/work/modeling/marcus/maya/scenes/model_v001.ma", "author" : "marcus", - "families" : [ + "families" : [ "avalon.model" ], - "time" : "20170510T090203Z" + "time" : "20170510T090203Z" } } } diff --git a/schema/version-3.0.json b/schema/version-3.0.json index 808650da0d..3e07fc4499 100644 --- a/schema/version-3.0.json +++ b/schema/version-3.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:version-3.0", + "title": "openpype:version-3.0", "description": "An individual version", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "The schema associated with this document", "type": "string", - "enum": ["avalon-core:version-3.0", "pype:version-3.0"], - "example": "pype:version-3.0" + "enum": ["openpype:version-3.0"], + "example": "openpype:version-3.0" }, "type": { "description": "The type of document", @@ -77,7 +77,7 @@ "example": { "source" : "{root}/f02_prod/assets/BubbleWitch/work/modeling/marcus/maya/scenes/model_v001.ma", "author" : "marcus", - "time" : "20170510T090203Z" + "time" : "20170510T090203Z" } } } diff --git a/schema/workfile-1.0.json b/schema/workfile-1.0.json index 15bfdc6ff7..5f9600ef20 100644 --- a/schema/workfile-1.0.json +++ b/schema/workfile-1.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "pype:workfile-1.0", + "title": "openpype:workfile-1.0", "description": "Workfile additional information.", "type": "object", @@ -20,8 +20,8 @@ "schema": { "description": "Schema identifier for payload", "type": "string", - "enum": ["pype:workfile-1.0"], - "example": "pype:workfile-1.0" + "enum": ["openpype:workfile-1.0"], + "example": "openpype:workfile-1.0" }, "type": { "description": "The type of document", From b495e5fbc3fccecd1e31d6a633e7875ed0d485db Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 10:47:28 +0200 Subject: [PATCH 215/295] changed usage of schemas in code --- pype/hosts/blender/plugins/load/load_action.py | 2 +- pype/hosts/blender/plugins/load/load_animation.py | 2 +- pype/hosts/blender/plugins/load/load_camera.py | 2 +- pype/hosts/blender/plugins/load/load_layout.py | 4 ++-- pype/hosts/blender/plugins/load/load_model.py | 2 +- pype/hosts/blender/plugins/load/load_rig.py | 2 +- pype/hosts/hiero/api/pipeline.py | 2 +- pype/hosts/maya/api/plugin.py | 2 +- pype/hosts/resolve/api/pipeline.py | 2 +- pype/hosts/unreal/plugins/load/load_animation.py | 2 +- pype/hosts/unreal/plugins/load/load_rig.py | 2 +- pype/hosts/unreal/plugins/load/load_setdress.py | 2 +- pype/hosts/unreal/plugins/load/load_staticmeshfbx.py | 2 +- .../action_store_thumbnails_to_avalon.py | 2 +- pype/modules/ftrack/lib/avalon_sync.py | 6 +++--- pype/plugins/publish/extract_hierarchy_avalon.py | 5 +++-- pype/plugins/publish/integrate_master_version.py | 2 +- pype/plugins/publish/integrate_new.py | 6 +++--- pype/plugins/publish/integrate_thumbnail.py | 2 +- pype/tests/test_mongo_performance.py | 2 +- pype/tools/assetcreator/app.py | 2 +- 21 files changed, 28 insertions(+), 27 deletions(-) diff --git a/pype/hosts/blender/plugins/load/load_action.py b/pype/hosts/blender/plugins/load/load_action.py index 79e42995b3..61dc9ce317 100644 --- a/pype/hosts/blender/plugins/load/load_action.py +++ b/pype/hosts/blender/plugins/load/load_action.py @@ -247,7 +247,7 @@ class BlendActionLoader(pype.hosts.blender.api.plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/blender/plugins/load/load_animation.py b/pype/hosts/blender/plugins/load/load_animation.py index a1be6e99ed..53d30d0a66 100644 --- a/pype/hosts/blender/plugins/load/load_animation.py +++ b/pype/hosts/blender/plugins/load/load_animation.py @@ -217,7 +217,7 @@ class BlendAnimationLoader(pype.hosts.blender.api.plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/blender/plugins/load/load_camera.py b/pype/hosts/blender/plugins/load/load_camera.py index e6aa11af7e..1e8d4086ac 100644 --- a/pype/hosts/blender/plugins/load/load_camera.py +++ b/pype/hosts/blender/plugins/load/load_camera.py @@ -216,7 +216,7 @@ class BlendCameraLoader(pype.hosts.blender.api.plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/blender/plugins/load/load_layout.py b/pype/hosts/blender/plugins/load/load_layout.py index 8d4c9fb75c..cdd5f7db85 100644 --- a/pype/hosts/blender/plugins/load/load_layout.py +++ b/pype/hosts/blender/plugins/load/load_layout.py @@ -251,7 +251,7 @@ class BlendLayoutLoader(plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: @@ -648,7 +648,7 @@ class UnrealLayoutLoader(plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/blender/plugins/load/load_model.py b/pype/hosts/blender/plugins/load/load_model.py index f48c0f8f94..4c6c1a8d7f 100644 --- a/pype/hosts/blender/plugins/load/load_model.py +++ b/pype/hosts/blender/plugins/load/load_model.py @@ -211,7 +211,7 @@ class BlendModelLoader(plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/blender/plugins/load/load_rig.py b/pype/hosts/blender/plugins/load/load_rig.py index 1cc722045c..12fca8e4aa 100644 --- a/pype/hosts/blender/plugins/load/load_rig.py +++ b/pype/hosts/blender/plugins/load/load_rig.py @@ -267,7 +267,7 @@ class BlendRigLoader(plugin.AssetLoader): """Remove an existing container from a Blender scene. Arguments: - container (avalon-core:container-1.0): Container to remove, + container (openpype:container-1.0): Container to remove, from `host.ls()`. Returns: diff --git a/pype/hosts/hiero/api/pipeline.py b/pype/hosts/hiero/api/pipeline.py index 26777fa252..6d9f24698e 100644 --- a/pype/hosts/hiero/api/pipeline.py +++ b/pype/hosts/hiero/api/pipeline.py @@ -110,7 +110,7 @@ def containerise(track_item, """ data_imprint = OrderedDict({ - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": AVALON_CONTAINER_ID, "name": str(name), "namespace": str(namespace), diff --git a/pype/hosts/maya/api/plugin.py b/pype/hosts/maya/api/plugin.py index 81c89017ff..c24cfad2d3 100644 --- a/pype/hosts/maya/api/plugin.py +++ b/pype/hosts/maya/api/plugin.py @@ -256,7 +256,7 @@ class ReferenceLoader(api.Loader): Deprecated; this functionality is replaced by `api.remove()` Arguments: - container (avalon-core:container-1.0): Which container + container (openpype:container-1.0): Which container to remove from scene. """ diff --git a/pype/hosts/resolve/api/pipeline.py b/pype/hosts/resolve/api/pipeline.py index 2d08203650..a130258e37 100644 --- a/pype/hosts/resolve/api/pipeline.py +++ b/pype/hosts/resolve/api/pipeline.py @@ -110,7 +110,7 @@ def containerise(timeline_item, """ data_imprint = OrderedDict({ - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": AVALON_CONTAINER_ID, "name": str(name), "namespace": str(namespace), diff --git a/pype/hosts/unreal/plugins/load/load_animation.py b/pype/hosts/unreal/plugins/load/load_animation.py index 5e106788ce..18910983ea 100644 --- a/pype/hosts/unreal/plugins/load/load_animation.py +++ b/pype/hosts/unreal/plugins/load/load_animation.py @@ -99,7 +99,7 @@ class AnimationFBXLoader(api.Loader): container=container_name, path=asset_dir) data = { - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, diff --git a/pype/hosts/unreal/plugins/load/load_rig.py b/pype/hosts/unreal/plugins/load/load_rig.py index 56351e388b..7f6e31618a 100644 --- a/pype/hosts/unreal/plugins/load/load_rig.py +++ b/pype/hosts/unreal/plugins/load/load_rig.py @@ -96,7 +96,7 @@ class SkeletalMeshFBXLoader(api.Loader): container=container_name, path=asset_dir) data = { - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, diff --git a/pype/hosts/unreal/plugins/load/load_setdress.py b/pype/hosts/unreal/plugins/load/load_setdress.py index 08330e349b..da302deb1c 100644 --- a/pype/hosts/unreal/plugins/load/load_setdress.py +++ b/pype/hosts/unreal/plugins/load/load_setdress.py @@ -67,7 +67,7 @@ class AnimationCollectionLoader(api.Loader): container=container_name, path=asset_dir) data = { - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, diff --git a/pype/hosts/unreal/plugins/load/load_staticmeshfbx.py b/pype/hosts/unreal/plugins/load/load_staticmeshfbx.py index 149bafcacc..dbea1d5951 100644 --- a/pype/hosts/unreal/plugins/load/load_staticmeshfbx.py +++ b/pype/hosts/unreal/plugins/load/load_staticmeshfbx.py @@ -79,7 +79,7 @@ class StaticMeshFBXLoader(api.Loader): container=container_name, path=asset_dir) data = { - "schema": "avalon-core:container-2.0", + "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, diff --git a/pype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py b/pype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py index 4fbea6b8a5..ac09d0c126 100644 --- a/pype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py +++ b/pype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py @@ -274,7 +274,7 @@ class StoreThumbnailsToAvalon(BaseAction): thumbnail_entity = { "_id": thumbnail_id, "type": "thumbnail", - "schema": "pype:thumbnail-1.0", + "schema": "openpype:thumbnail-1.0", "data": { "template": thumbnail_template, "template_data": template_data diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 43e02283c2..bbc01d6b66 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -31,9 +31,9 @@ log = Logger.get_logger(__name__) # Current schemas for avalon types EntitySchemas = { - "project": "pype:project-3.0", - "asset": "pype:asset-3.0", - "config": "pype:config-2.0" + "project": "openpype:project-3.0", + "asset": "openpype:asset-3.0", + "config": "openpype:config-2.0" } # Group name of custom attributes diff --git a/pype/plugins/publish/extract_hierarchy_avalon.py b/pype/plugins/publish/extract_hierarchy_avalon.py index 74751c6807..dd1f09bafa 100644 --- a/pype/plugins/publish/extract_hierarchy_avalon.py +++ b/pype/plugins/publish/extract_hierarchy_avalon.py @@ -2,6 +2,7 @@ import pyblish.api from avalon import io from copy import deepcopy + class ExtractHierarchyToAvalon(pyblish.api.ContextPlugin): """Create entities in Avalon based on collected data.""" @@ -148,7 +149,7 @@ class ExtractHierarchyToAvalon(pyblish.api.ContextPlugin): # Unarchived asset should not use same data new_entity = { "_id": entity["_id"], - "schema": "avalon-core:asset-3.0", + "schema": "openpype:asset-3.0", "name": entity["name"], "parent": self.project["_id"], "type": "asset", @@ -162,7 +163,7 @@ class ExtractHierarchyToAvalon(pyblish.api.ContextPlugin): def create_avalon_asset(self, name, data): item = { - "schema": "avalon-core:asset-3.0", + "schema": "openpype:asset-3.0", "name": name, "parent": self.project["_id"], "type": "asset", diff --git a/pype/plugins/publish/integrate_master_version.py b/pype/plugins/publish/integrate_master_version.py index 7709f089fe..ec836954e8 100644 --- a/pype/plugins/publish/integrate_master_version.py +++ b/pype/plugins/publish/integrate_master_version.py @@ -168,7 +168,7 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin): "version_id": src_version_entity["_id"], "parent": src_version_entity["parent"], "type": "hero_version", - "schema": "pype:hero_version-1.0" + "schema": "openpype:hero_version-1.0" } schema.validate(new_hero_version) diff --git a/pype/plugins/publish/integrate_new.py b/pype/plugins/publish/integrate_new.py index d4a094a975..d342ba2e39 100644 --- a/pype/plugins/publish/integrate_new.py +++ b/pype/plugins/publish/integrate_new.py @@ -501,7 +501,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): data.update({'path': dst, 'template': template}) representation = { "_id": repre_id, - "schema": "pype:representation-2.0", + "schema": "openpype:representation-2.0", "type": "representation", "parent": version_id, "name": repre['name'], @@ -685,7 +685,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): families.append(_family) _id = io.insert_one({ - "schema": "pype:subset-3.0", + "schema": "openpype:subset-3.0", "type": "subset", "name": subset_name, "data": { @@ -726,7 +726,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): dict: collection of data to create a version """ - return {"schema": "pype:version-3.0", + return {"schema": "openpype:version-3.0", "type": "version", "parent": subset["_id"], "name": version_number, diff --git a/pype/plugins/publish/integrate_thumbnail.py b/pype/plugins/publish/integrate_thumbnail.py index 23d2da5f4b..28a93efb9a 100644 --- a/pype/plugins/publish/integrate_thumbnail.py +++ b/pype/plugins/publish/integrate_thumbnail.py @@ -130,7 +130,7 @@ class IntegrateThumbnails(pyblish.api.InstancePlugin): thumbnail_entity = { "_id": thumbnail_id, "type": "thumbnail", - "schema": "pype:thumbnail-1.0", + "schema": "openpype:thumbnail-1.0", "data": { "template": thumbnail_template, "template_data": repre_context diff --git a/pype/tests/test_mongo_performance.py b/pype/tests/test_mongo_performance.py index ea5ea90aae..cd606d6483 100644 --- a/pype/tests/test_mongo_performance.py +++ b/pype/tests/test_mongo_performance.py @@ -108,7 +108,7 @@ class TestPerformance(): "template": "{root}\\{project[name]}\\{hierarchy}\\{asset}\\publish\\{family}\\{subset}\\v{version:0>3}\\{project[code]}_{asset}_{subset}_v{version:0>3}<_{output}><.{frame:0>4}>.{representation}" }, "type": "representation", - "schema": "pype:representation-2.0" + "schema": "openpype:representation-2.0" } insert_recs.append(document) diff --git a/pype/tools/assetcreator/app.py b/pype/tools/assetcreator/app.py index f025af9662..366bb8be08 100644 --- a/pype/tools/assetcreator/app.py +++ b/pype/tools/assetcreator/app.py @@ -396,7 +396,7 @@ class Window(QtWidgets.QDialog): new_asset_info = { 'parent': av_project['_id'], 'name': name, - 'schema': "avalon-core:asset-3.0", + 'schema': "openpype:asset-3.0", 'type': 'asset', 'data': new_asset_data } From dff8409df2bcb071db71b6e32fd7ecc63ca2fccf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 11:09:04 +0200 Subject: [PATCH 216/295] changed "pype" group to "openpype" --- pype/modules/ftrack/lib/avalon_sync.py | 7 ++++--- .../ftrack/plugins/publish/integrate_hierarchy_ftrack.py | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 43e02283c2..2bfa0125e8 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -37,7 +37,7 @@ EntitySchemas = { } # Group name of custom attributes -CUST_ATTR_GROUP = "pype" +CUST_ATTR_GROUP = "openpype" # name of Custom attribute that stores mongo_id from avalon db CUST_ATTR_ID_KEY = "avalon_mongo_id" @@ -102,11 +102,12 @@ def get_pype_attr(session, split_hierarchical=True, query_keys=None): "is_hierarchical", "default" ] - # TODO remove deprecated "avalon" group from query + # TODO remove deprecated "pype" group from query cust_attrs_query = ( "select {}" " from CustomAttributeConfiguration" - " where group.name in (\"avalon\", \"{}\")" + # Kept `pype` for Backwards Compatiblity + " where group.name in (\"pype\", \"{}\")" ).format(", ".join(query_keys), CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: diff --git a/pype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py b/pype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py index b4a2760c93..68d0f9cf55 100644 --- a/pype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py +++ b/pype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py @@ -6,9 +6,11 @@ from avalon import io # Copy of constant `pype.modules.ftrack.lib.avalon_sync.CUST_ATTR_AUTO_SYNC` CUST_ATTR_AUTO_SYNC = "avalon_auto_sync" +CUST_ATTR_GROUP = "openpype" # Copy of `get_pype_attr` from pype.modules.ftrack.lib +# TODO import from openpype's ftrack module when possible to not break Python 2 def get_pype_attr(session, split_hierarchical=True): custom_attributes = [] hier_custom_attributes = [] @@ -16,8 +18,9 @@ def get_pype_attr(session, split_hierarchical=True): cust_attrs_query = ( "select id, entity_type, object_type_id, is_hierarchical, default" " from CustomAttributeConfiguration" - " where group.name in (\"avalon\", \"pype\")" - ) + # Kept `pype` for Backwards Compatiblity + " where group.name in (\"pype\", \"{}\")" + ).format(CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: if split_hierarchical and cust_attr["is_hierarchical"]: From 27d39867845011deae20fa3605dcd0822585a095 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 11:24:43 +0200 Subject: [PATCH 217/295] temp change of avalon submodule --- repos/avalon-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/avalon-core b/repos/avalon-core index 911a29a44d..de43124167 160000 --- a/repos/avalon-core +++ b/repos/avalon-core @@ -1 +1 @@ -Subproject commit 911a29a44d5e6a128f4326deb1155184fe811fd7 +Subproject commit de4312416704102a3587802d7a042e75efb99d49 From 1b46a03a61f43ea3288757d26c3fbbba9cd6a969 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 12:11:21 +0200 Subject: [PATCH 218/295] Nuke: avalon tab renamed via AVALON_LABEL --- pype/hosts/nuke/api/lib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/hosts/nuke/api/lib.py b/pype/hosts/nuke/api/lib.py index cee558f88f..a8bb08311a 100644 --- a/pype/hosts/nuke/api/lib.py +++ b/pype/hosts/nuke/api/lib.py @@ -25,7 +25,7 @@ log = Logger().get_logger(__name__) self = sys.modules[__name__] self._project = None - +self._node_tab_name = "{}Tab".format(os.getenv("AVALON_LABEL") or "Avalon") def get_node_imageio_setting(**kwarg): ''' Get preset data for dataflow (fileType, compression, bitDepth) @@ -148,7 +148,7 @@ def writes_version_sync(): for each in nuke.allNodes(): if each.Class() == 'Write': # check if the node is avalon tracked - if "AvalonTab" not in each.knobs(): + if self._node_tab_name not in each.knobs(): continue avalon_knob_data = avalon.nuke.read( @@ -489,8 +489,8 @@ def create_write_node(name, data, input=None, prenodes=None, review=True): # Deadline tab. add_deadline_tab(GN) - # open the AvalonTab as default - GN["AvalonTab"].setFlag(0) + # open the our Tab as default + GN[self._node_tab_name].setFlag(0) # set tile color tile_color = _data.get("tile_color", "0xff0000ff") From fd67d8924b870a2aacf4d67530465ce271aa68cb Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 13:19:26 +0200 Subject: [PATCH 219/295] update all icons to openpype version --- igniter/pype.ico | Bin 109515 -> 126450 bytes igniter/pype_icon.png | Bin 1723 -> 0 bytes pype/resources/icons/Spine.json | 22 ++++++++++++++++++++++ pype/resources/icons/circle_green.png | Bin 35899 -> 88727 bytes pype/resources/icons/circle_red.png | Bin 36200 -> 127047 bytes pype/resources/icons/inventory.png | Bin 15767 -> 57718 bytes pype/resources/icons/loader.png | Bin 408 -> 60326 bytes pype/resources/icons/lookmanager.png | Bin 2408 -> 42562 bytes pype/resources/icons/pype_icon.png | Bin 3793 -> 110945 bytes pype/resources/icons/pype_icon_dev.png | Bin 6890 -> 109276 bytes pype/resources/icons/pype_splash.png | Bin 3793 -> 82287 bytes pype/resources/icons/pype_splash_dev.png | Bin 6890 -> 84102 bytes pype/resources/icons/workfiles.png | Bin 205 -> 70900 bytes 13 files changed, 22 insertions(+) delete mode 100644 igniter/pype_icon.png create mode 100644 pype/resources/icons/Spine.json diff --git a/igniter/pype.ico b/igniter/pype.ico index 746fc36ba29274127740c24feb3fb834424bfdbc..f0c15accc44729d95be27d5f5d047249f7065337 100644 GIT binary patch literal 126450 zcmXV11ymeOkltmN#oZ-naCd^c2X}YZ1a}W^0fGc~2yVd_f;++8U4uKve|PiVyqTJ= z{;F!Ky4q#{03ZMY`0oG$$N-_%0D$HDePH1K(X{YDz|s3N5t09=#Q*?I7a)L@_5bKn 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 NveFZ#bJKeA{{tG>5R?D_ literal 109515 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 P00000NkvXXu0mjf8ME^t diff --git a/igniter/pype_icon.png b/igniter/pype_icon.png deleted file mode 100644 index c17d6ee4c1806c78a34d0d15e7a7d47f5be47d59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1723 zcmbVNZD<>19KS5uWbN9eR-BVguQwPidar3N$+4{IlCF(4ZD<2+$IxBwo+L+eFTJ}q zY1}jsRy&8d2^Kf^At3mI!w++lfy@=GFsv0O>K8xRZB##~6N?l?>vL%mI-L%8@Z9s< z^ZcIQ|NVc*V*|a7^^epe2+|no3lG5=wT80}zKwi-6;4~VzA*zq8d|JjL(ZIi7(woT zNQ#e|qtT~0L6r$!R1<*6$r?l>$lk7;#tY-XL=zw-DFN)~kFH>-BnGe%Pn3#kA&{2( z@;VsK55$H1xZoGDu6^j<90v(xVDe~A&L{?#3t(kl4z8_j5<|-nb3A}`TLRJ1XbcUh zIzU;1!Uc+AP_Lh$+0IUudIDuAh9W5sNi#Uja#SZrd(p~+L20^}<c7irDze~L085*u z#*t(;n<cVtLe*0w?f3ghiXj;WhX~x5R!lyJE5`0BLl_u>E@`HuDyYTCC)7zZfI&?+ zOpvu2tzuN%1RX}^c#Wh9$}*`86ond2o76L9;i5o-43L3h8W2m@uv%I*RU@tb3w7=I zHUZGJ(P&M^9d(iAnh3+}nSy3i9CAmr5ueroIRp%KQWrqa6jXD!WsSy#bikXc9#_>& zHBhmt$|yq<4B9>-DWaM+IyPMZVcrA*%!(RL`Ei<#!>GC4oZI&}#c&k00gbAnl$`!2 z)XPzR&cogYg()NQCVyA3C~!$tmw9NgB=adiYDx-2Yi{I1YDU$eV5psY^L`{0is@=n z%D@9-sCPda=?Ss4pJj1|pv&q;qg+HWOkNQ{Bpkq?a|lTixdh|&B|*}Q1J;|s1#hPZ z_jkhdVg%O1dss1<^m(fH!>TZ8r9kz*_&@It>JltLK6B4JR$*GX!}Uo9jOuiybcVr1 zWtEZ8a=LK5V3k1t6Rh|H5vy!V_w0cU+H4v?(*MYd4Va-O%`C5j?iBRaUGt8F%9B>X zZrDNo-Nf?QrsA%`VaKqRwN?c`YRwKPu*2!FmHjq8@g9QM`Xk})_~=$)ZGFA#lVD<| zdj&bM_-nM_do6s{x$tM~^10yWg@%^v1s#2^ZecJo|4MNUbE)>_{5zqmQ^Chv>u+z_ zXJ44R;VT_`vZ?Uhx#AS!T-kQP9vnSV+C`;GyKe2A{rcUT1xGOBTvFPCM~Z#DH-;8% zBiGLFXmCA`?SH20Vyo8D-)0<l9{m6U7t?bmw*0akTaA|H?7>e}#O1J0bhxgxF^%y? zkwEyBqB;LXk#KCQ`_ksIkL`#zhUK;UW>dwNo<4Zd5yao3+M689&h~E|vr8TFtEYxt z%`Z!1556f3pg+|uFU8!azyAR_d2{=<)kC(#&b+@=|Ki7w=KY7+rlb9{6G2CF)1|?A z+aBNQbo2EBfwkUxeKzd;><oGGt7lu@aQ;y`cGYan?QwZsr+++O%sp`7_XCI6)``mk Z^5La}-^|RMTC{#Ik)DC@`}+^S@E26NH9r6V diff --git a/pype/resources/icons/Spine.json b/pype/resources/icons/Spine.json new file mode 100644 index 0000000000..8c70d52b25 --- /dev/null +++ b/pype/resources/icons/Spine.json @@ -0,0 +1,22 @@ +{"skeleton":{"images":""}, +"bones":[{"name":"root"}], +"slots":[ + {"name":"workfiles","bone":"root","attachment":"workfiles"}, + {"name":"circle_green","bone":"root","attachment":"circle_green"}, + {"name":"circle_red","bone":"root","attachment":"circle_red"}, + {"name":"lookmanager","bone":"root","attachment":"lookmanager"}, + {"name":"inventory","bone":"root","attachment":"inventory"}, + {"name":"loader","bone":"root","attachment":"loader"} +], +"skins":{ + "default":{ + "workfiles":{"workfiles":{"x":3877,"y":1247,"width":500,"height":500}}, + "circle_green":{"circle_green":{"x":3877,"y":280,"width":500,"height":500}}, + "circle_red":{"circle_red":{"x":5748,"y":280,"width":500,"height":500}}, + "lookmanager":{"lookmanager":{"x":5631,"y":1253,"width":500,"height":500}}, + "inventory":{"inventory":{"x":6335,"y":1265,"width":500,"height":500}}, + "loader":{"loader":{"x":4827,"y":1247,"width":500,"height":500}} + } +}, +"animations":{"animation":{}} +} \ No newline at end of file diff --git a/pype/resources/icons/circle_green.png b/pype/resources/icons/circle_green.png index b83369a9e341520d4eb8481ee501b2874f2ce356..6b5e27c49ee18bd3e1b4249a1e06de89c5827b56 100644 GIT binary patch literal 88727 zcmce7RaabH(=8C3;O+r}1rP2n4^D8m(73z1TL|uM!QCOayL)ig#`SF8F}}ZWE_yJU zo4vZK)~uSd<_=esmqbP+K!kvRK>klk><0t{<juzi9v1k|=)z_M@WtO;R8-ONhos1t z|HMT(ShzVj7``*IKtRyMImb=Xi78<X3c^0J=V@qY$o7nwDfaXj^(ksZ6~C;E@m-9U zq+WU0eqH{yN-J&kqIHQ|t-2tMPP<HNY1Dg@!D(wjmFn1b;B$VT<=A?!b4i21ZmtUb zB~?0oOL2;mv+G}(M`6Hs3%njeB?e;)kZf*&H@{T*Qs!o<D$luonf3xb_Q;>$P}N>p zq*x?{%3|bD*WmPdx1X91I?baANQj%f9&>w~p~j5wTvp$<&@b5#pN+(c7>w9$sDk(Q z>Zvg;E#3qsWZJbXTqG7aQY$oq5YYPuq4T4r6i@@VpRZ<RnoeorNQd?m>b|x7aSKG2 zRSQF>mP;<N{Gl7KimMwRXV81}zS*hep<kuFP8c+TyZUzM_lI~0WcB>K)L2KY`1V=7 zROIa#{j*m@7OmM?=u|Zf?jj6BD_rvG)b&rXF)8_P$w$-9Zi0bN?q;pQE8<P2kB;)B z!pjL&t^Ti{4ig?i3iYKOOqX4u3$uZoAlON1Izm7oVSaodA<{DNARxX#{3j-?;+ApR z;r@$g(EH$doagC0>lqdV3(<|)PAknP9!}1n)aZ6pi!!3eTW-8K+4g($N#kPVE@Y9g z(bak|^4_Y;G?ZZ|L2CM|SOk_h8kBGV1pFn20z@DCz4zqJy6WRw%F%iG>DZs+ZV1OO zg6M(gBO^QNs?ksT7s;BMej>SwG+2ni{~!M>RsWjj5Xx2LT3)Wx<_yc4V(-}a>XBKB z-vBut1{a2obnI`Z$SMjs&g`6L$urHCX_l6I)c2(ogcf}$MqO0Y`(<FJSRNurh#{?s z0n5yP-x>+0!OVZ9UWlR1KzlB)vE#vXnY-=R<jSM$z)0bB{jag*;Kz2|lwoDdmD-9@ zsD^!#<IYvBGsi+jnh_ddb(#r^%?o!u*02S<x$z1z{w4HzQ3e(Y9a46YxD<3mvD<1A z7LgFSGmV9bMVt~<V<ldB+GwaS3=t6mDMgC3{~$!*r{UqJBeEm^n}R1JfM?4?kEVa) zY@!X8v$hEADN6WZ(F<FMm9Ubqf)yE#mBY~h<}ge8kp}teYtUEcym3OYY-Ef5D2e)D z6*6ThEpyA<U&EA0sdFM^{E7A7^YQ6;QyQ*|k>;`<Ebevh{$$w&Z$pV7w2IX9oSrTd z!ykdv6_Kn^Pr4^cNUXwB<DRrwam+t|4QMT*{;pOzoTv5)27{o!B-dOx(=0^z^Y~XD zvY*!Piv<bf3Jh8~FspekxdyA6gf71!9C@axMLi7GYAag8*K}N{x_)U56&L+hb78YK zd9HOi7aJJ47nt*QwP}bI&0UfzKWhsSsTp`Q+}tqp!&8@to^oaf-Q*1z$XPm8Gul{4 z==$RvTT5d?<Pl7Zz)p|(fsT2m)mBfz0pixXr|qgaE*nKIutGm5eolNDP}!JJhy|JM zQ`gl|)IIKo|0DxT#Ncea&QHWrtFPJw8+GJC>*ih#_jY&^^mzQ+PeJeO<Urfpz$!7f zL0AxHmn&mfQX}?Dk+1(%ir*^FcI!I|6S=}>i%V~*ba;R)mtAA!38LrCB$^zL8Q<Mk zpvRi2Dy~@TW^(m5a%ebHrCIoNT$HZ}zqDMJ9^?exP9b?Kd@^`Rx>MX)XtWbuD`K-z z=0yzng)+_-R$1ZXmJvX1c~J99!8rHVfEQWtqX+>~;UwFSVEXHNzrz1)XqIpg=d@Np zZ%K`if4>lX9`_Tznc18v;KqxLKQyr5ku~~a1dYzx6Gmv*7X`m9foD$<kb*8T_L-t2 z^$VTXb525@5W{LfCY-ngg%%JYA1;1w!Gu&U{=`hdYJ<Y;QH@7bpo-Hg&2|v`VTFKd zfHW|jw4um@V~Qcjg(H9pU*+kM(<TfE50bBkhY27EtNEelx-el(&l@;B#y0SM7H?eM zn4CB8Xbox~krs%?(26^~yncQ)t?rYP4K8-{Ouub^!py>t5F-yIKip?h6K=+0CU3?< z^B{U}3+z?laj`LY3PUkP+^}30jmRVe;xtibGlcnEZjHzsP-WjyKm%7?m5^V#_}Sb~ z7aJR9ejktToK1q7Lws?ywWNGN85xQbDAO#kNKawoenq`MCkrXk|IJL^HH}u%l25VL zT*0kEI2~T}X$r#3bjP0&YX(nN!GMc3eCq~FqE;DiSk~w(YxL0?pVd_V;~qry*U5H> zD(58>C|c)FIJ~d~@W)X0^&!Vo1QtS;)g;zi9`(TlQ|LCpshQf=3&F;psu?V_jZ;&1 z4Lr7Qe%iQf>X6+kz^wAT?Nut2$Htc^mVW_GMwk}rnN5wrTEq!wdDD!}B2OLa%WWv( zW31f#NRb)0@791hM?=wvg_UG&Ox5K#TWXl0hu2fOizd(X*_e-48PS<8Bc)GBxf(~? zsA37ndT>F5w^3q6(Q+WiGIH9_XfS6*K2hBIrbyxdZg!_?Y)|>Uo_*!+#*0iBZ*oGT z?h)o>RM(X@SKUe@A%~8GDE79??CY3R0mB?xty!*f=dTt)!=Q^zESt`H0W?%K)_rT1 zof-Ewzqm2BiGq;ncp_n22ds`GrLkR{g=qB-HL@=y$bD1THp1%lFzeH5R^j!z>?&}M z=4+dCPKRRmy3~bO$}NwlLLM(mUSth)HbL1_VFEnAQ^&@zf0RzzJe45M(s5vY1SVh* zP7iS|CGJUXt0*nNT0gDE5p^MDns-G6*&3a~?BVK$hUU64xI9yIV1&%vggGVaFC6$2 zS55T;XR<<OXucBGe<|ozvDQ6zOH?{Un?W&l6nP%-Wc+?PIDVx^o$YRj5h`TbcoVWH zll$>ZLAQT*c&20Siw8{)u1ibdIM*w)!qv+?fuJlf2%fH%^+(w~7ugwGM&qykrY{iG zw;VV(Lz(A*W}5{!$wBU(^5G!Tenr9u0*p5zyFJ(QMV=~jDxIibgsh_df*lG{cnm(D zcO}4j8pSHIA)kNFF9=_F4xS7ohBhUu&)JZXS!}$VI-I)J(^-Q4Hf`mzH74X?^fUJt z$rFH3W%FlPCm5865zhS+S?gaxK|mC4wHqZ?(~7T=vJsB_+q43mfzI-eVLQR7@>h?O z52SJn_va!iJ0n8~{$cdbKdFAv7fcQs(x`=%pbr!&Qncn*ERn1R#Yj;ce?pi`W%(Kf z|MI!&XE_n^uzd8-@)z(e=yZ5?IPPj|Y&SJn#6yvvq*y}%XlCU|B&2So9o!n8M+;`2 zo(mJ3uv2Z?0nWPU6uXav6D#hr2m35pnf-1q1g5_!xKfFFj)KX?_TxuBZGJ&Rn@dr$ zif-7+GvjR()1JmE7ger?z4hmU5+KQ!!T#>V#yg8-;Ht=apDmAq9BpD6BhY+wx8>*y zjo81O3$0rNdKA9Ml2WdAk#w!U9jPX1-zd71v>aO!w`V1?Bjha1(V!_{NlP7&0wD$- zA>0&7Ove)l`&tlb^7@j*irBlL8Ke?d=75YG3lP@hIGiNXr_n9MEK5ija(Viqs!x`9 zVfwuUGSkPIGN!`rj8;ZEfdY3o<>P%mPi{R|!KB5q{73@(|B_%Rp+)$qp~+bytqR3# zKn`-eUBED8=V``LNL&%(NCdXyh$Z7clzdL^h_@R&*qNP_v58X2Ax68;dHG~1e~aue zIYQH?v8}t4%m`b1#^DLc772638F-QvCJ#<uPPp6bN|@N67Q}2^-gN}n^F*#A8iFvK z`qTbRcXoir!gQ9=ZQ9%T*X$@ETUd;OT6;XEoL#gx82`yyKvVC-*?r><>YU39o7~4W zP<F0TRmnp~W(Q%V_sAVa)f;HnBjXNo=JL)UDzg^s(fHLTju#`Q>LGgkq~U*@Fz_(C z7a_Zyz~vFF>=B4il|*PYQgtt|wQXiZ^R=_AKf6mZSTE!_j0q$8!_MBqX`>vmaRVPS zal5tTMGC9D6G>OScVMW*F08plnrT+Tx?_espHDFpCbN^-%r_l8VTZ()jNt6Pnnz2= zn(yDvo0ciy!o&SC<7D%8#pL3nGyX@VoB%+8vK|U=&$gA`X#LH&!%i*gCzFsO+lWKq zMNJveqyO4jT?sD6vLt})Vzy|?9wda(slft|L+YExD(Nng!mKP`j-bQTo+h!eV@R&8 zeGITh#wu~X>1fGn3Yo!tzwDogz0abq!;ZiJo^_Bo_;jy3i*5e+WO7wWC{)c~0B7+z zdA{qr8j9q>vz^_wE>ZTypqLAeWANAOMgq*uB^6eDn@7xppDAhnLFnSf%>FXl>Gm?c zC^`feVp6D5qgW-uQHkj={o(oGj;gz&fwwKkbit>E2!bNT<{W5U`w7joLl;l=f?L8> zqccuuwtRk}C}w+iDK|dOKy|9v?WtYQLz!qpfoze5i89GCESd89u*hR=9T|ZV!Z1Q5 zCy6wB<=(vqsop&^#5pO;yo4Ddh5|<y!^63rsj`mJINy}fV!a=jhgb&$K+QT10Kfqf z{bH}KUccwcLovP>a%&JR&vry%3ZS|2Fd3iV6VFD9fdA18pM#5D@ErC5LQM&iNG>Ka z<hWQS{-Con?oMUWNj1X?W2Tg(u%Qxfa${|s_izoTr*gh8Z)&>dTkd(=JTy-~w=hsJ z{qD`K3e9A{nv3aXu0wUFljuY|{(k+{wLouea<$#Jy2StVO(2ETPuzM*x)1vRiwU)h zemBtsXA`*!6FIq$bLTvX(9Uy575+rn+!||6UVGWg*5P#hZEh)BZWomO>aa-t-P9Wo z5hf706cLxZ|3<YmQ2Rg2y{mYZY)v+btv154i9S5%<y6!5%i2IHAd~jh^;Q`)<}4g5 zma~iHF%}Jk{ZqCk?d~|^%pZsnc67hBoM4<{9o|yzO&u1bUs`bdkFL&6f3V^YTp5=o z&;}+VLOt&f(|hG^h1c83{)E0S-aQnJLj6W75Vr<!Gvs^x!}1XNDZV!`zIMm1bPbLj zcuCVRId~8EKKKSgVA_jVVA+FWMHCtS2=egvKa~l_e|;~1pZ}wKZPTQC*Yfr7Iv&-{ zR;=U49+dzBsQHrP8oNPaV`Yo7pqEjH<m+yp2Tse`MK<Mb^LrFQEXE0`c0EOI|L%-s zPUqPvr&dm==Cj~&dp6t-u60Wm?B1gcI~4Y6e*5m#{-_1?910t;FDHkfGd_Nf#rsG< z&`Wmya_Ua+(eM_N^LlBJt`a+N4^(UFOq-_BZ4OVP>h&^eYP*^k7F;|vP*t11U<nP3 z7=7mq-2uP4*}pKf^LuI`v}_Y??Q_>{K6=&OYzx58EPLm@?g3Z?uRd?pFPUE1LwPlB z2LBapCa{Olc4b6^8aG5A@ua&8C~Oi^S%n+^IqxP6mtb2Uyj~wq-oW{DaUN5zXWspG z+o;&93&1)~G-go+5$x=an{6c=lR|qW>i)B;nXY||W{f%$9mO#`Ru{Nhul1A{Z3e2D zs}rG#<NPmnxQ$a#IvNh&Z0F67lp8ycLleqbw&xFu3l!5LkA!Nv7vKVJ4bO^(t~5!k z+J3eeI5>g2QkYMf){<jpOsPXUl#BkizRb#1U5_R^!B`&9AAy7$2NBul&TX=6ZFj`y z#pM&{2TH*Cv#eAHqZ@}~NV8GI0Rj)F9<9C9Y4X1319e1^ZPR5w)bAGjL8T^)U!O66 zTY$<AZE;@3lAm45lAr#$n{d*~V#mn=4*;@(tx{typ2adghki{v#=$9*jV5iqE3Ot^ zBVnc_RC7q3q{E)j6Q<rocI_JW6+|WK79j?nbcMUgy?6z={e9oHbRzHDx^&xYu$hj% zKfq;_x=}rRZ5l(4s}A8g1vE&*HZj>n)Prwx>?9^rcbPx#Iwwfrucu>&MU+lWh#gX? zXstrRAl)2e&*ob-NgsANqmFtL@#4JAV3Junv+K$T_V3^uZD4vcg`16!js01)@%$s% zqc^=L9K%UGJd?leKjSacGZ=rKr2$Yo_XDjFaZ)HLZEVcZ=w<SRaGJ_*zqaTV&^Jhg z7%|v$=yjTHXTa;#FFWW3oLe#F!P&d#AuTTG1)<LC2UJQ$G9P#eBm%_xQ%C9afn*&k zFLiC*4yyBJVN!xBgknIY#&-Bya#Rrh>pY!B>jl70wRa?%|HFbJ8kgPqyW8ew{lq0d zhH4<s0H4oQoN*$#Bv!X(62ORYwC8cTt$B+;5pZ^evZm<DVq?DKpQNZO{$Kh^3RA)0 zteVZcrz5|@*j{|BK=ly^yQVlWc|h_lbX^RTSu}dLF{t<&E226@s=3MFeCPV^jrBaR z*>m+M0L(bmr4FC5PKcNDSZW7ne(oIGta@oSUHD1BTa4i`hT9Gh%c<`Sw925fi(ohG zokESTv}EPp%*DBa6y7f;t=|sOAML*}LMP<t|NS7|>loIr=M4?G>-m_kzkiXG;88Ov zA`R|8U7il1x3hW@#J6x`m3Rb5*fVO<R(ZADhPB%*3p6#ZiCpKsT9H5n9-6`T*{hDL zdDY%Z=%g)uo-PZSRjV{mK6xOVrOrP3FZyLzbltVAdKo4H;|3`~_Y>2mxA*#;pc(vv z4(Y-t`)TlQekv^=s{<Y!)keRD3oN(xc(;;DuXKztQ&YPY8Gco*_|Li(ld^tv2o7+^ z%CKYN9Sj@hc(>NtO7o}tdLIqEkm4LE?Uu*k(^JbTh3tpyd)rp$CYk&Q<c}vt0eCuR z8`=1}IEuNR9gCNXlWB&n`<9T{|8~`MwUhe^Pd1jq6nD;Z2>S%9Npe!my<IKZ_yn!c zJfJquV-2Ui)C)GtKxv6Hn9$z#nW4GjNLmcq*0rw0x)3pS`u^aFgg=q!X_m=#oqNY9 z$|x`w`W0&XC|C6URLbgcw$bi&9&)@KzG`)D01oNXgWja0o97)Hy#*badIoj7nswPe zI-6h~?K7jc&cNs@PPjXZ90*C9(-w8rr-cvFU*1VawGKxA<c(5?=mbrmE2|D1ymd3j zw2{gSUe`D8Ix7A>fKB+B@{lki8<}+a+9kJwVeK-LVY+ei4{9GBiD-U~6wddD#m<AP zn@h4?Yj%lBjT0429@i7J>c@x&?TLo(f~)A4oRAaipg3z2S-HWg`t=|t*NyNJ^Z>IZ zt8bjyeDOq&zM-@6@1t{3TMCWdQXNIkpYox-1Fy|C^=i3iFktLVElbX0IfK(HSz0Km zXn{emzs=F~^1e8$2bl6ytyF17hI-abS#eO4c}!SWBg6RIs_xpe#P12M|M59VL-dFv z(M+M6_i;A9BD#ESMaOA>ptQxE$|ia5Hv{drL9DN46Ug}Ff{nl3G(su`bV9m=4zVe0 zf|}T2EPX3zHJ*8qyTwu_;~T(u<Fdw!|9nnKJdt7c66w@3_rly8%DP+li}vqMTgIMU zEbG#yy5I%T{rg`-igwQT3GI9b834XdR+5TcNLA-}bagtm8D(PH)ubqu{p9o<I$wA4 zzwkx@;SJ}2v$Ty)pWZx)V%zK%RJKtjjBjyoXL*GrA@xFdJz}}#YcV3;;qV_<kkaEr zkmIw_TR*nl;AoECdNzv>xLSflhEAs#cdOpv_`p15f4BYz4`3YVoLfQyKhEg`&((YT zxf=Rg09C36MKPe$-_7Du=zcH!Tp#6V-<7vVF8bvyScIVXw<s{!5TMAlhZbm6s@7Cq zopiK~+Z~)}#<)G#m~tDx>DfIV8WAf|gryT!{#|ESG`1`!X6epj3p@%Bk4k*rxd(Y> zx46!Z^9v9tmw!sgv4wECJ6+(V7<aXbVH2DqDtVP2`^?+Ahtt54k=jQWe_=eibON-~ z?mP>dD5H*TQ&5{Wd}h@s!;23`lT>P^&E()Saha<>6wmZDzWD&PR%O5BF_WZrGYQW@ z1=H^Af`-e!{`2h4=7mi3nP<r}Bl~&d1dz#zkAWY|4xkU=%%{x_BAZSXiV2yt+S-pc z>?xr?crrW4qAykTyD%bpbXisltgPR#QBjgHBy*49-L!l`F7|9<=-lKo0d;N%s85TF zdI4=(RlR%Rl@X?k*3#42B)n-g4!*CEsmcmIHDF_7I@73aFQ9lcYwJuo%|9=!)#rmo z5Ar<@EuH<{D!@tNEUB5jGMKhI!8M%r-?$6f9s1otg+ZNZ9xra4Hkd0Dls+L4YC|Zk zb2yMrhf6q?gM;Z+1J=>%d1NVeeA^O`053KD9Xxiwk$Ltw&40#8qJvL?bwEgYc=8MA zU4hB{Z32rpmG7?6-D&9oX-9Zp=@gNGAqzlTL!wlkkm0p8i_||$X!PnSlWJ3C4Eok7 znF>4LN}-2USKZN@g^vAcme5(WlJ4l+WMHu5G}11wFw%V}&zzL~X^M(mT>N%)=(X7e zOg!q1JjPgM(HJ+*1Nq)e^*Xw3XN!QIwpotc*N7+P`cgHv?0!n<i_|8m-w!AnLw{}; zu}6&xdk+uN_Lk_7dIM$d9n%x|_o-^-7Ow2fCmWdl)}PrE1hj@n8mC{%RB-;wms2PE z%fF$Plf)jc&BdCU{yx|Ql7Ah=<+;F1TrASCq!HGa<YRaHH$sQ8zG;CnzfQUkIL<Ro zv}pT{GgR_f|1X`gB*3FXv>H`w1h~_~{61IJoYW!oDkmg+-x6+{u3oa>D`1sU8{njG zb>f1<w7x<!bn|!>Y<>4K1QVB__7OibSj^TZ5)zKe3SOP-OujqX4vt^668RY+=R$iE zR|7ddieg)zCboVK1O`1xS-C1V-j#G#>MOfVFjot6P<<h}NkqfIvfGP~7&@9~w+-gb z8lRI|L5G#`2^e!Dd70ep^Y}O&^&IVK=Y(xbCNQvw*Kl|hp2+Jcd&bpyDDGNY0-ENd zw1UO%<nxc6XF$x9afi1gqCB+B02)saV~lMpkd24+eZ@1iz{40kO@A#nuYclv{9bsN zE%*&mQAVG3ZikX-nA*m7IBays1HS8J!YY~iGf<=3H{}Fa<#o~}Hkt+HuqX!V+q^TA ztT}1-H+%SNJ=Tnk9p&EaW_vLUR-cTnyZ-5?TVR%+T4avBy(rrxuzr79Fk8K#8k5Q# z2wp07M0yxxo%}a7=P89V_s-gHv8Ap!2?|(sxE|@7J82wDw&%t1(Vwn6Sp6-x0LBxn zV$QxABZF@O=emu|4<<2KV~Rzi+1NA_b=B-C1MHVb+{$9M#mnN!$>E_&o+;|(^?=7V zJH$vX586BWdUi`)D?QNJ*VANt0S+on>FUpHJW}Ap^Q>U^bc-HVi599z4LZ8qCTMoq z3$36fc+I^%C~NZq6o1%eRZ9&1FZ}E3kE{sgZp7BUmk6Jjp{#!Ez{6(x>0n!%XST-v z6}mqo%fUUotfnNSqZ2QKo-4LQ==DV!CJ8xJELnJN;cPG`jSFctrY>_%`aKs-CDDQL z7u)(CS-nCYUhJ|eG&+~O2(tV0qCYy*hD~bEjMi<4Ver5AJ4He@yWiIGq_XX6It<!$ z^0=hqdijCpD0gl@1GxR5b+6mpvUMFXzXt)#?O8jlkHMZ)0Faz-I+YRZXo~{%F8We! zTh&52<00o*a@PX1VICLK549)QR5Iq@peP)3VHSgWInQY3;Xc)|>1vX8*lL+PDVg2k z-CEF0ud!<;#KBB`wZa#|pnK0Y>W|UNc2Mp?<s>>R-S9HrPJ!vOLaeFj#qobJov;0s zymNImme4@01p&H3KQ9G?E1(nkP7(ZZEuYlL!2tw_hpQ>bQ({l$aU*prw26h2q(oYB z@IVKjeJ6>aOLO5c^oD|&-mm#B_sG~htQaQu<2=WIK8)lZXr#8CIQK4VL3ehd{Xs2T zH!3b)_^<jm<_@zatvkJiwc@thfh&d#P-6du@wg%;>*)IT*fgOzvVBe7*!u&I8cRDt zy>x-fBwJOTFU`^ZZNbN7xAN=P?#Pfr)tjbxU2|BRE)xnin5i0n)D6__MKbDNE%=;; zs0jpAd=bu1n(>pVTfc4838c$_CJQ9qa+tX90zEm`%W-lwKl1#2GP=FBgMaR_!n)>e z6JUGrZA|7Sc0Z44NJy7rF_Au%ndFJslh`38wz>EE4D3d_MF%Q#nU*})EXOWo?^&y{ zVSH&AEE_*QBm2@!vk(JFu@QuXjN&S;oiXgzCdvRNzZ(KNm220WOK<p}Z|dbV(o^am z{9`!D?BrIid*#AOQd<ynZtQo8GKAyf*SqL<s5V&r0e}W#GpN!`z>!Zjrd{2V>lq*T zQ2k{nmg})@UD_I&kPirSHCwMh?H0^y?5PhWu-hz3x0jrqmr79@R5Cg9`a{kAH0K7| zuk!ejZ|l|YjA>E3_ASTLRH>Ye*VBbi{cGz5pa}akvCg~<=YT?%U*nfG0W^Vc3(*^J za{)DssQ~J$MR3S%>mwSMKJG;#29@q^bi^^*@)4*`a@WsoZs!o`mxGp4f((_zZS%w# zg)FrZWpHK!Ro^)73;>GIh!Jve5`$$L$a(1qtX}9sjf3Mu|0*`yn|v2HPgQmT5AZ1u z4^ltSt+I68MM1fGzpEkS*cQbM<hL#e=;Owpn6{VWdI6fFHYyvu&G*lDp+RG59X546 zD7}yXoxZeEvQ_^X8l;vY{Pie+?^;?dDk`yeIM|S01K$dTlS~hVUWB?8ojo9vV4AUv zJ>R&=2fVRC{kHEJ><Eg=g94r&M|$_l=cRhq=$S6+>^p}hrGq;qI~c%1I)?gB-!pqK z64SP{sepC?z1H5m>DA|C7iKQj^{h#*O9?{Lb3TbuCX4M#a5<|&%L4AcytS&vNiZ>T z7ChIJx(h#0%W8(io<o*Gb2b}Z8G0ksR%xExA3fA(z1e<$vm-q>Nhm!vi5Yuy7OkgQ zcMFg@psl6V(8-P4l`jGHhu68;L|7%~n**w)<A5)xsR~-8xpFAXgsb8xYmk}Cf^Qmj z4bYv3{#M{T%!4=oH`&>x0A5+J5bL!R;d2qSB4JoA#hT(sDP}Y@Tix>9&8QK`?0P|5 zNu6ZGT?paH{a;*XM-9+Wv#n7%-;|>9JLcx1X5NX?SC&}scu0;mBLU?^v5HT%Ty8=Y zZ*fwifu59fKPgc^$w-8cifLq2aPbVo=ir%3OmPj2^W_A+{BM+p;j0&6<h8sops0)6 zT6~5a?@Ka68k%{5%ryI&Lnv1S(!rk&jCb`q@mGGoTYUem4Y`BGNFyvb_)_v7`~avg z`hbw*HG8?Y{C{2mPD6<%0x_mnTUtdV1r*}Goxo?7UnI&#mCX>BbpO0s>0ueJYs+ri zHOZX7P9`EFk)4sn^y$Ua>05eAf}0`QCO%gr-^pTZ<vl^*|8BlY3JcfpZ$Mg`w`f>T zD_5bK?>mPSDfpaj3c87eKedP>JaO;Vym?OpfXk$hb@Fgw&pMOKYAZ9k3Uf-}fe)PE zuNg=yyk(oOZid9QVS`y;jVi>8M3dJ?O%R-ZJ}BoBiGnpa1T#o}GZdcVD>9P(!jd=> zxmrsGU*)*9U`{qhQmcY#7~?k02=y0My!Mx{z6BA76~M`8Dj=)SMWE6&3E2Zki?HHd z-|r4$Uk|I^HG?-N(Sb@qk40_AvOwZ|*~bn)7mQ8af{k_`7G9Xxx#~{7+?^7Z-QQ10 zp<6(hcboF^Np&4fb}bvVF2ZB->QpzrDv5vBdD6q!%5zih79f=iYm786{MKS@3e$13 zjm^ZQy#SG3MKdEV*sfD`h=^{MBl8Fuk&q~=;DE(pWfkk1kQ6}~^d%>~CJ4QQ-^8Ry z;MMo#cvbM}#8(Y-Zvv8TT}~as&B&lj&sd_%+p!nh7iZ>EOalh18cHl`XAmhW@n0Q* z7A>l8SOQl&6>8eCvKivf9V@2y;Ij5BlXX5#&5k@i5;CV$)3MNb-DkoKI{moCi;7im z=l0q~IT-W2AA7BbzeD9)Zi4W;y@@$@{A0AyW{4H`$aRPIP~|$__4lt!-@V_9wC6mt z)$u3~>BcZWJ>RCFKlR3P=z)tN*B=SM0N)WL0aEz+T(b6;CM6O!VwcJeL$;jvivZ_5 zW`FtPYhHUlo83|W1y&?6RBG6#L}##b>pu`I(@I|Fr)OC99&2?XW%kR(Ao#HyAdLwk z+?(s}HhB{8s7`AE&pb8~b9Ri_=?&L_+?e^ER{PzzQq0=~;3ffl0+&BZ7NTD77?642 z$V-xm9T6jzy)YDziTf(MljCYX(ngWU>FaAe?x$hZ-gDzaG5~_nq-rj=du~vj3mM`_ z)-Ex=<(SBb7`9c((pz(B=eKSdnqWegcDy2_Mc^h4N_PE9E&+e<x)!Bx{>*Fvr4)*r z-Ehst_4sxnf3W|40mr#nWD`aggmHtt{ZZd{b~{~djr)1;*c<_r?8Q02wrA^TOZ215 z-ySRX!}g9VJ0X>M&Qq-FkL~P}VM1_>kTmIw5yv>%Mbbxne^z6k7HdJYT~qS!<G2sE z+oSsu@t(|ob-nap)Vd_A$yQ(`s)4%Q8Iyi>)JQmu7R4*Z52R`%gZnXaYiv%?*9B~C z@nR377{9INC;6-wW*y$>y%&)N)HMOwJ|!L2&N4n9w-ee&!tk~EYjT(10TpcAttp$0 zBl9&OyvaD4DolL5jM!&YhE4a_DIJTNSJmpFgJ?Oa9_R&(90;Sy{I+-TN!Na>kux~i z+kDm6olp&SMn3RC2KKM66dK<wEn4+V2W%Tk*gXz>A5QIWrB;{op<n4gh~(*v+W{_P zM8o@i3cd|ZXb}!Sm^u_?dpI{au5P|SzF$J@E2B+-vRucDYo}h-m7AcUOJkIJy)Y=W z#NEH7Zrax_`&33tx^7`owNGd+-L8n2GW~VH<Km?SeHElcNR1PcgB~y;#o8m0Lx0># z5`~|OdL%}wI$4^{4_x#B(wp<}^OEK3<q0XU>kg<O(3`D-3-o48xgUXqa*^KdsreRv zAGX}u(KA5~v$wi^hO<mI!eq8US62O>+L*ic&$#eC(Pm>uX->l#lfB6IkqJu^gh(x* zC4Uy31vm`txDWLgW_DJbg-_~m&W<;Ywi~WL7%<zs5^|X03vnyfHc4z=@`Lc#M;Hm} zxYA!CTuPbSj6|z{=;bCikBH65@V!j%9Gt|tm)6#jJkWldGgYDvsd8#r6jE8-b`7W< z93S;Eu~c=k`l>P4QyOe|C^iU?9q9W0Vn28?X7+rl9DH@L+o|6r?~&I5N&Xl&CYN>> zSyQSFtLN4T^RI?LFG|pzU^m{o?3?o8V|l1egD7tPs}X}YBC@Wx7jbELXwk2LHE?id z2xiQej?+_D=?}dvGpn-LjYD*goY%qRhOyXEalnIy#vSA}FpI<}Ko^l6FX0UH`ELw9 zcI|20Q$gU3b5l9CUNs!!<{RL<T5T?JS>+$kZ57n=u+%!j)zg7I5AS|Go@N8C!bS9& zoT7Wx62m$`W~`<38)H#VMptqZclPqoAs2i1`*m)@GF&y<UT7nIR9tW}E)?msL|Rlj zkr#@NVFYZoxe|$>$bh48CaNXOhDpedo6WJ+^4kQ#***<aWvtwC^3Io0mkA+wU;{F$ zT&0xLCa`IKv_<ysb3Ub01iL_fV5qJrT(zQ9RZ%J;Oz5-O;iIj3{U*a{JH}aC!(Nm3 z@Tq%T6T?Z{&?!Z~?@!jp*Ez~#el$j0+Sk#2y9u5zg<2y$da0J~^htm;I01A)_-@K8 zxx$7`T>TD<dW{_I9<9q=U@ob0UEDm^0cqosynsm%ae<|GRT)yBPZx`ZBR}0fjD_Li z)To=q;V-QT)f$O^9kl2^S&ul@&(`U_3B#j1d;I}TRV$L)e`sY=`9|H;vK)rL7q7$( z{LDMOb0EiThkOyZBi#D|Ul(fKJ$doBY>`|rtHldZ5T7rK6qQ88KPmsD2xKPL-FJKI zzjWa$sa**+6Y9=^UZ?)wj1K5?ZNysxt3Z#`;u<L8$Rgkg%l=H<=Var<E~i3+_eWDv zTxCHa^e?htKrfxaRV=Fab8ebsYdcjhx@jXKCYRxXdJu&Q3AEjq(SfVlto=2olW?<B z&#O$*S3mf>u+_^n^)EaIZ#>DVBjY>NqM=vuxxLlq+^r;2vUL<QcAm;5`@ECLU5&a1 zVIqDQPNaO?ZaEDf%;DVZ#1ty+NF(Lpz}WU5b#EwhR%Wn=Wt!314(I3d10~vIdlPeA zmFlhsz>6ok23azIbRgPiW0E2`Qs60(j6kt3(-`?g-*4y9e`aVxDv9Z=A|`w--BN_o zg1hL6(*-9D@h1_?Ot;Cv*vTFV{N{m;nkJ%ts5JcJn8vkL5}Swp_)no)Is|I;xzOu@ z9~_QTGOe?oVc|_%cs#25IYySa7icvszf)C=DmAE82<2TcRrQ1(ynnNp9z8H?hmf}I zfkl2#kcQGnF_=eIn?TE{W}vL5md^2^tMsCBs$lwGq5^9$d-@EhfM*qZCd){gAKTnM ze-j)RIyBZo>OKYiu2xoz`dL(MdHDs{pKO(|l%&R4*ECky#<0B~8+$Viz7V|!M`1YO z`Ybgq0#n{v1N+RIAm9Ta+y5B0Yy7>rGKoUu5`kXG>oYiOqE`hR<>bqd$bd~xPt*AR zeFXgw4;9JIe#}3pQdwN=y+u8y@D#HQpTc&qk?!8X2r(72`-o`+eTf%|`(Oou_EN3P zYIzFlrnR)ahYuDYW(>lC17p&9JeX_QSDpmh^2W2>3hu=RPfD=m6LMtSjQ&y9e(-J6 zf=4)Zf3sifoB##Me`WfYxy(Aks$TB+)82$LHx7ZWEqnZ6Z+%z<{Jko>DVS;0^EU5q zUHZX<39Tw6VlSpC!QOGP%qFd6dQQb3yM-OE|D+$i&;|u?4!G$&4kje$A1rBV{RIzR zI=7jjSJ91vGSxyhH&c(gW1sGfY54cdDyYy9Y*0A)YAIJ7<}2R<>6VdJ6lsK$r?ARb zSBU<2SF)?<V>lujkn=`T!`|;)-Y5Z$fxSn1ZF8+>F|W}LSCwPpIBCGw6{!mREY2}Z z4wWY#S^kLv!#&(|LbQeHrA%4oS&UrstfN2&t^!RhU>niyh2O%yii)f4rDca##P8YJ zIkF(<y9Jql!1m=F3m=OeMEo*$sCdQJlYwzH$W^%-6j?RGD3p+c^l)@ZSJ41EP5qE4 zIJ_CN`xGQmj4zf5hsti3u`OYlSnR-^>jPur<Y$y6Hij-r{O#5R$?7=YaOatjvOR<5 zP3F=4nMa|}WBzDPCcN&@p}9Bk)sn%6<{ErDG@49h^u|QE-S!#rs<LWJVU)&15Ok#% zk8OV#?k(7}M)H*0?5U%u0$c|UKUWDXE2@yie4l1>7q#f<lxTzx9-7{8Pd@acw)~=J z3=V#ClWN-++>awml~U?rm&vp1wWR;`m_MP~&2w4nx%zH+(7SV*eaa<nsQ0E!Rb-PH zux%snCbq5nxh6U7iw^8Ew<9kVZku#V#-Nfwd_8&Q?Q*8O+cb!J;PLD-{1j)dJHow` zz$Tr-#N=vhs%(k#&ZYlPy84`xF0g2PJsEtuTa=+|7E%hB_+Q5Zgf&jU_wfXgp49;6 z0#@T6yx+;kuwhIYfHQ<?kKpOaBE2_Q#(Rj@&~1}Uh*adfi(08b8U7gZ0;8ridtK=g zG#XCBghKb7n}SyzZSuzf*BmkDhvj`wUa#hkhyN5=vd+nmXIlXF;sp~*Ehx0$(&=X{ zDYt0aG@#Y>W;faStKb0!=z^4hZchdDsP!(&mAgzo5MKWcRKw+)4%3GU0+^~S(n=KR zF_%*s)bXdA|CH$IHUBg;)O@z-p$7kPC%dj4loacgX>+5ogxln^CG=%9nTBhU5Z@l1 zFi+OiZdw-b!s<n8vUkzsm+4`^uwATi4gh?MS%-pQ`E{=^77ha+8lxW3Mf3f$>75#8 z<;oPGf#tEzI7xbzT*YF73fOD_Rta3l%I;UL8s_S>eOfHKAqSg{mqyvBH9jtm*v;xX zQUzURkoGr<lOVT(7PlA?NtMHOaO3k;(W^^yMrKiMd9rv`h0<wi<jO5CQEzyQY)a{% z&tfBvHFphjkZxcob3ztW8?=1S=f#H5lXo}Af~%Nsbeq*Q!f=;!|NQCN@~wTRi2khS zv0Sicj}`-*3$mTV+lzf%nMMsy(`_C}E$WfEjQ;c+MubHkw2$aH`PB{L^XSYM`S{=! z{=p;l75^IxQOr}r$yjZb-f^4c6D^M-qHCD}6uD;S6zE=#D!I(R@qwW%*-Tvz(i8;d zC<|66F^w;8%AcxE?Mg2LwgPZ(fMMCJg?#$8;zNf1oR^HlP+byj`oAleUR~l5m<=pd z7BMTSD$+O}<^5!ZBHhFxADom9GphzGxKmAOOVwz+#Qm=^^Y2d}J?qu4RYnhz#%XPW z?R;xFmR%mMy~1>7f(TzUTB~&rd?Hue3~v}-tahCT(=I}a(yh0i(g7*d`$V$indxEA zkjYGVbGeS!&H1cR-x84JZ7n=9)?ESf(Z}p=&YrJZQyCYnIohX+rMA}veiU2nXKQH> zD;+3HYM_mTMYI2|@62L3>~(LicfmI=_O+nGPP;(G$iD15T(+ypDMf(718OM}zoXLf zh-C_}%5nIIO_ag4KV)v<(N3%K{8!akyYudq)sr~VPuEPRI-nDf>09VGZd*cxwmEw} zs#9N4?Hvr!Hc!^0OV`%EX_Y8u(6!HfMvH8b>T|zHuaH?Vznm4Y4JGYH3y!4RBRZ$I zFH$~_MW&Xq#u0}X+d8!%r@HnM=XT9{G_qhPrV%_yYD&knpSHTq!)27lUHM{Bcm4d+ zhGg^Pkz1Z2irEvP$0MhO4DEef1~Xmo#GaWj4M}Z^Fp!<IA^5~Mp95_*k9B7sxQs8a zN7*@o?2Z4cVk!0w*2Dtb`<Ccb@J?ARhxn!Q<z@#Dtc`J3e>p~5b8@gs3VnV2MR^!G z-n<007_xHFyhEEfWU*|C_m$_ByMthsJG)Es>2@{~Q_(O^9Qpzs0Sek|Ho@R#_6u#1 z<DO)gb6(tvkdvi$^Esyv&&`TlCAO6Tqm;1k$IdJ!jUn6i^MV)fMuDCzu(5x4+s7x$ zJkgZ{V-cp+wG3DGA-9H^@g?K_tg`dEidQ(`cNJ_56M41S*|srs73PMzXs^ZIl3xCL zrX=urTpmmNoZDb<$X#QYN=Kl|{%NH3r4V~o_jo^>1vjFle3m-WDeR1ghttoO=e2!D zi6ijP!}yE+Y>e0eF3FL1>2hHn@+b`TA)rv6EY9gU*{Yy=GYoaCzHGwk_2rh{6A5Aj zZ=aU7D>23HB~%Q^B!m|ng6P2ifDN87W;my>&(GVio<mteY`tds-N~M__-LL>{BM7D z^Wn=~kDDl{P7D%7kAiqz`{5QcvRXHv*3on@M~VXpD=)7{GzpVfZxkE5gpjz{+&?Sa zkUH(cAA@KtLb_b!))ywd-p7!5^m`=^0x)j?Vn$5He|gp_)Se{g>$v|l3tu4WCm99Z zA4U53I`k_GH1{c=c558Y$;@>egoZJa1)L2=!JV6ST`1eeX6Ul&bt9!==U?I@k6}C~ z?#gdOVLadRV80AgFiH{+$~C7&_`CI_(#N|r86w1W=)6U!|Ap#dahQ~xSput#U;52v z{UnPn4%P2v0?G3_%)=Npkd43G1wVK_!B8G5Ad?(!5Sja!IW|B3xGQE!Oz-XWo-`)s ztg~pO#hRx87l=PTq}L}OjO<?>V}<n;`-rq)C}>B>3~6(roX@jtod_5H;uRSTG8eUz z*9jhDn%IDOmR1&cnQ)B_`x1*c?S6-TT(q+7+WM8S_P+C3Pi%m<NO6Mt_!1ph9bN@) z;IbrUy6yr;Xte?$v<x`U`JMS#$iD#en~&YMUe@8;-oDV8I@^yoCBTSGa^?#O7_AIu z!F&G!pzgnVp^CGQ<32wh=9hl2K0Xz&PZ2xjxHGd<V<FPw)#uswH`g}ruEaplHc*?` z2c|M3nd@8mO%!c>T?T2)_czgt7nc8^yKa7CYoCXE@^4cU!Itj3?$BE*1O7E;AGXWy z4r3k{1Y~9?3toHIVh8+_$Q|fcB~HC|!thV5qE&d~-7DInt&i&|_>9Dk{#r|%Z#a6X zJb$t{)vXNHL@M&U$ftk1pM1Z_z&4Kid$qHjcb%8sRZdZp5R2F+HTPNDTm0FIJG>f! zbnuTv^Qbj<$7L;7{Ex78%_i_z-38yhXQud2yGzmeZ@5Zs3i46Cg~Tq1+98x@-jbJ& zf(m-QRIZrhfediA5l92oVn3TL#KPwJXvz|n5rU&VM{uPnxi9Lnu^IpIHO5Zam<5<n z=6cXvVml+I$8J8FbcXSRy#=ROu3Tri*;J}Rae&|kNz)w+hw?Ow-D4OHYJ4ygd4vD> zsIxo~ITa7i+e@=BQNS2U%e&SCSoLKeCy{pF`B{!Wc=54m7@ObON3D%I&k$QM6K&dd z%p7b6f(5u(_$(4d%u-*Gl&Enu{@WxAMg7?{@M_8(-vTkA-V~>#Rvr*U{S!dSO_0k5 zl%-;dP<t<*zwBIvisjZXL4_Sb8K`Hi!Sj!;CXLPR&!>%t`;6C@%V<?Yp1AH~0itNB zBB_0O>hcIXSctmr|C#W8uZqW=?dRBChbD(t;hl_igvuO~5LoG67|8|~zSg!ts*dCT z()F$SUh6R7g!nJ;QJ9bS1(quH$_ZkL$oxqISS?tlQ^*kt+;rx`yqfk(vO&0V0G<!( z9Q;Ckp^=g8!tkc6<2jbW=17s6w_odhCPoK~@fh<vxN)46Ka^5aM)^EDk@ZT#9A}Z< z;^-FYjVQ$pU5VneX+rbKly-U?+8xO-F0VBUW&f}`U7+f%xwr8hmswmBCVD;jzcPeD z14zBV_-|+q;gr;ulokZfo`YXNs{tm3Tzjm`<>aW}w>}IUT@7wr0G0rp(3o3BY2w!H zf{TH;13v!$HPn|GiS~NblQU)B2Z_@U)@}E8K_@mobV~|MS67uF=At-~>wR~mB@lYp zxx~2M6My>2x|~@nNqlr_dP`hMF3_*amcHKYz>BVT*@Z8Vr{t~+I8@vWPl<^#&s^J8 z%E<6gn}RIfxlD1j%9st-YjR;aKFmMBn+%pq^;=_Kvq-&(0k24zNfPjqRhY=Uo}pV+ z>rcJg<sZ?ZbOerjBhT|mGqmXLS1*rw7?>SALh}e^CFzPu%-d4hFUI$3C()kWVbsBH zQ93-36O$KtY4U#AF`%0D5iejncJ*?ojVI50AYmQDrn5>?`5uF6yvRVP2H19ZoF<dZ zR&7(Y+#PmA$fDJ$Ha~nEhNbiWu*wFcH^Tf!>`I5~u!5^iwp9K9BIp_layoQvfk+l8 zv}^k>qAW)0yA@D##vZu#5EI+Mg$jc|tM^<$e<J-JP8f$OL%TRK7!btba)@#b-jn(r zd`@h78D1{xF@Ukh`}ix00*Na<7RUm&u`kW{<j7zBLNi3^BmkNA5O_JKbTe-0y7<=L ztv&^$O!(oW0hT8FNJsN*3b|aNmx%j&_~Bw%a+uNDwVbL|EM9R<s@7pHrP04(-4jgt z?Kirq%dN*;N=GQWspneG+}nL(dTAx*l(MCA#D$%e9+r`oxx}zl*!A?}^iuirJlcKQ zO!kq?0k<yT@sJ?8P^d!fGv>A6ec#>6!aeaOXsKNK70}7Ba;LxAbE{rw4!DU<NxYH0 zj~Of?R73A`UL81$6KzP`rm3b=+76582v!ps`WMF+`jeBz(cDmfkpC<<ok*vc7`xF< z;aHlV2r?;aL9q$YEiY^LqVp~9??~MHBksbl6H|C>I`#@*t&T4s=W<G7=q^2#obmTO zu8Fz7JrNmVrRR3hDzfn{uKC{+s2Aa>(m(m4lW+R<(GQelbO!8mIg4U<rusZ%!Z8s0 zkAIwvx1_z~At=;NwH?A9AAslstY^nPahH1|+scXJVu>zYa0dhVjhC&~qmZ$Y=IN<} zbZAFU?Qw$Jx#TB0?SiXB8C`5#!g&;BeU`zys-eprA&@_b`GuD@FD~TR3~gz9jFbpN zsbaRHOO=PdE3m?_^)|PIz_>2AT@J}z5(}un0?zgBG)70i=@pe+qNFfI0x}9zboKDh z=PSeQHg><q&z7wAu~ifB6_k9-<hE;7I>Xj=YXdbeNt~a(d1VZxy_)if4A~t=<m39p zg#-Wg2v3Bq*p9l{LBFn5v^HF*B#w97O#uA8E*sf|Bhh*pD^*=;*F--L8&&3OG!6xw zEL&kSLp8VN(Ds$TDBkE8k5&v`chbp8<6HOr<msy7WRWe6@I_3cPZODjV~2eGj3szR z4W|wEK3}jx<SgPgLbm@WNqYKm_`v+*Q+tre&(IQzzpLbkx2^8h0gd01bg)k`@08Z^ zFcQ=0b`o*B61$Q+>>6PfWcFTF-#i|$?U#L8Rf7BKU`DnXyt`UXpVWC1zCL^72%7Y= zmAnu)(+{p@r~QqE(-R&TNpv|9n<W$pKWWR8dmk^Z0j>hYAt0-?UA3-63J@=Rx-uew z>2Iqut@b=+|A-!}(AOj{Dc#-wz?@pka+o>-8?3+G!(XD4*B4T}@?0K_FD>HB^zowp z@w@+clcx+0%5`os3y6}AjsHHVfo0xf)gAZkdQChIi=^tA&{0G>baJjAG4EihMH_DR zqS1<!=|2o!4Z`(2Ccrd*xi*yUX4|;P5{16-Dg4Bu$>*tNBajq>v-WKXE#OV;U1mU) zeYLX!^A)3!GlTvo;3>=&=~jy^p;begMjjp)t!!k>@j#W|C$8J;=-IS-a)^l|<;4!? zd0!WoBJw6UrvHKQ$7q@I%0XoZr=<i|)2!{#8;p)5<W>22?L{cG_lTiO4Rz$at<Oz| zA+gBpd6f}9k-6Hk8=E<9>G%k-#cg1XD~{Ft9VUJILS7(LCHJ%t6YVg~<w&(bcXMO@ zek8=reY6$#=EIlV6ZK}HUGg^Yi-blOD}Cj|bO}&j4PYWa$*SuZZd?ELS^(yx?aE_n z4Ij11v$-7-DYa^4Sf2FpAcnICRnbtaFsk*#H%jSCi%h`(r&`yvE+z-cKYj5O=Y6<< zPCTeilTRssGx{Cs*A}u2nBWhU#EpM@b7Tw-t)4qnNQ*G?=$VEZFtZ1Tdg?jx4FJnL z34l8c1mVB+0A;BiPO|=|_8g{z<(FAYUeWVg4#^>CR!{@)?`&_V+VHpj0Ymms3o%Z| zt~*7p;K19Ej+KPvFQW%`v6Q#fMgs>XR+O?nOb5SS86%$5`2;7H#od*DZ#63LtqBo5 zk68bTcv`x0dh=j9SgAWm=4DABe7ii0enz(vBx$9G>P4!J-TAqQ_@#d{!nLJ1RIfig z*iceSk+VrhZ}rhY^vm?=`sE5p7wPGLcJiR(PK<@XrfVksN5C;VRHoQwB)5Z|1Zr~M z`jrUAv~dO(kS)0~p6<d#BHzzAIM~m!2+Pcf(F#(d1T|C;FfF5sT}C5UL{5s>3;I(X zf@)kC;r?s+@l}-0792m!m+W#oOPjETlZNYT@USi0dU54b+`+xtGr{`&O>YBZ;Zsw6 zkVWTpZ`NzkfnmAfLPJi|hrvCfeuJ2^N6zZ$!#R9+dNluCCil`m{orH|xy4<Qd{X1) zASC(Mb3-I*{!?lEr2dO^|9p*e5{lf{A9;@Z`{GZ9^gn7BnIk_PO$<BufjbW0c$I3s ze=|Ex*O?5CFMDS_9AULAQ$_N)iT(PcRXX8)u{z7o#q2W|N5U#Ht~*`Swj$Dy{A^_= zS8D_F3hV>JW9)VUA;+6FDfW5+>+2R^Fq(t<9^u$0ja-)*sn|*LGKy519@<y@Sfix2 z`F-TN^@O)aRyVJ)HYUD0?;GL4i9VZO7&3YWZSgO#%;ZCza=pT@Q17qN*p8F^#$sJa zO(+GpHksI{+7G6?WnN0MSJIku1M#0EnbT5f0eeIUV836%sr0?vd_tjGL)L67*A~8r zX!I%(sD*kx|35DPS{JpAg!D-RZb`7I1d1^;KjRq#9hT`}%bRZafMR#SBP|o6xAM6o z_g(cWxflt#er$;kD7##rYzC4;_mKVvBPQu_@-pKJX!ddE8`IjiQEm7AM{lnb@5fwU zL-%RNRUyqUx+Kqk%Dc3xGTsx!$#r~^#aUd(#;Ph=mD+z`{S~snm_+IDhuV4QAGfO) zz-ue!U2zgs#jYY-D9jOLbt>s#QFPRwgV*gZB27Q(^$&NAt3xU?NfW6NQQ_@8q15QV zo?lB5&nil{tNwG$X?3wPK+n1?_p%IDQtHsJ(hbV4=E2S?yq-NE*Y7~IcWe;Cuz>S& zYs!1l&=%vT`+qcj1w$NNuq+S=5CQ}V1h>Ej2=49<i@Uo!i+gZ_yIXK~Tio5<-QE4| zckg}wVCJ0Z>h9{Qp2qPQ)q|L~wnugym~opW`mo1GL`4cyY&*T}ACVKtoY%q;lXG`| zk6sgB+t<&nCzlP^5T7AFs%J<M6@kd~oKi*jo2MWVf_@N5K13rN?^4m^ySb*=I9aV5 zv$?ir5s+nFI85Il)w?LqmL|&#t2vEe0@$L~<&dW%@>&|%hvyO(X}0LkG7b^kRA8zG zFJ!lX7=^o!4#3x@{Sz0{)c&MccBV+<)C`F!eG@?&PGAF;GI)sVq1i>MZck`~?<RMA zp?O~2#s5F&42s46f#v9-3G3V7EyI5f0S*&1??3}<QlyDz%0~RCg{bh6^Bvnd9X4~` zI+|sGg{)G-U>?@epz1(igp^^QRY>B)k0i36jHSZ^6Zh1@Igbe-cD1N9OR0Ophg$cJ zX6za}&aB`MnWw{3dET6m+KgfL1oo2XS|nG~0&ED`<`iGaK$iBY<vnm-P9~{U-ZBbA z{y)saTFg8F$nUWb!mm|Knwj9f^!xbzC#X#=lzTL4-g45xZwp97^=b*^FGVxdIbB;e zY2>k4hW*8-_?tekQj*z32eTp9Hwk4W$~QDpWEPRwA3q%VyJ=->mibb11=jvg1U$p# z7@7ph-R?tFdH5mO!WnXzx**TKJ43FFZAaCLK-xFWC(X>!@twZv2Z*wjCLbpic>Jka z)>%x`xr~j@OB>N$tSM*4|Luguq%Kj0kN$}^a^fM6f6nnB?55Ab#(QqI&jT~}%9hVy zyd*1a3^M_Q9%74D^So-)qD;(1KrY~5nOM6)a;Xz?dN4C`5aJc?CO=DQHBOC<BZXtH zKK>2LQR{jgSv4R+scJvOs(ioY>b~|s`ql$ILy>NAXKy8tEQ1d(euxfoCfQh#W60Z^ zy$oXEEGGZPbMGq~gHJe1>7C}(+5F%Ctn;`-95%5K!gB4@(4wta9>SX9L!8`6(_i`= z?2+(V&K?w#R>ow0(psstYD6tpdez|748FvQeC=&iDlQ6RiIUm@Gtc99D=9qFmh4(p zD3g04#iK>kOoj&pXTTmjaM~YaT)x0&U`>dqY8_YdJM%tmR7rO}wKN?Hm?sV5VS~J> zilvQJ_jk^IfB2-10j~OI&2RIEM*=K`g*=)dW?531q}M9bkCv<Hg^29NV7!$XmHUTn z6ZX-94o=Wlh(UFBWfqhAudZxv>PE)k2v+^kJj&iXm=m$j^VJ7L*ZLIs=P-!ILY7#; z$-G0zDuppu=$CTqZ6GRgZ5{%O@?L^>^8?)dtI925XH*2nzHWnzf_tTlIzLsLBOSN! z#?6@F<u~Ukx9gjgco1=0L$lZG%cAiM{#oKg{h<$4@gShGrvPFX7jgwnb0iWn32oIS zyi8c<w6IE$TSkIN{_9Al(*D$A+lJS#jlYX=#^Luv#K{b*;^n!Zu!zu86Y5q0rJXnB z6$;%BakDqq@tS8NbDeIo)*;6igw`>npQ?#bHc40*0();u`dEsUc{`h8vuhRR^7QF# z@b3}(z%E*k{ai%5cdTfAG%c<HSbn_7P#ZA6B!tzQqYJ|y9DW)ilW;_Si*pzdes=hA zaFIrD97@k;8-C-$kR-c<J!3jqOTS-at_j}D8_P)z_pvkaay>c`oMa15J9c#5qU&)l zGOCoZ1~YiUTuj_m6qrM#4k_%ep_yp|7kfOR%OzhQ6ZuN7fFfUxoSEVYq7FqVzsxxF zNv@P7sjuqZ_9jIZE7gm|XK$ZrdV>|^*K7Eb9=^l<`@u?w)TpNNNUmKf;zWaUwSRyR zq7$m&m$i|-aR~j=jh%JD2;ZCOBGJ2cofu3#tlGwoICZ9xh#Pax$H^7KR_K90wO&Oy z>(FqQltzXOy8ffiRput(<8WzAQ<TQ0m3jyclHtq1?>}K8A~rTQ68Ro>6R;Ao9Oa^k z^ZWK3>eA<wH|AilfgHg@%K9FcVsqx{^&cZr61ZtBU_&bS=Or`2o{@92(@)PO8Vr|0 zFl|^<L%dGA4!CL%Ff;^Kmp=%3<3Rvxu46phnQ7D$NUV$UqW^@Xh9{#OA2yHT&-a|l z&IhaSm6+Cgd{W=J8e&zjAl9Y+l-*>qw`t**`T`Tr!=ZOFOC7oeu%A8;X87?|#}^Be zBa7WrnDrE%a<F3`Zda6RQ>azGs+w0CV^sV@df3zJ>w>9m{OcH=zqL0JU_TPOKpdru zAx_(l5P$BPbTlk%0|8E#<3;^l2h+whTh%dO-aL?p)QFU}=Ff&RTF*8BujKx_MI}Wn zi4+D%?QsJZLtrxxzO1dH(ym;~xbg=ynk?h4H9Ckjh3^ZPZzjsc<Qcy-;xj0&cXU!W zFhUR0GM$C)FsQ)C!oxFe2bsOC7!5y@Gl==-3wK~HXCel~b(Q3mv^8)7y4eleTLW7) zq!(3K^hS2b4}(Qx4sX(=-0<gO9OS!0i+i+&JrAsl&5EW!LmT_qWny=qZM}8Z1dlgt zQ&8B1@MtQ|ps|q_q5hmiFA;(GOssR<nc*xU3n{)${UH{nSg&ywZg>tgQ*w6b9Tcut zi$}AbO75uQZPYDyEb1W`y3_ZrF{chDivvJ9VY}UBLfekjpU(g<);fzH>*^{||EXJ7 zgphr(CWlQR#!$$S=RuBKU7`G8zmc1+VXiYQH|_HIs>o=t`>4$2q_BthIDU|mP-^2T z+O61}idGbnU;WC|dV8Xp$U|66z9R2&8zuhTxG|k2X^d_~{%ifr^n(MfEtV7<%O~V6 zSX>yyx`5+J!V0l+9HCVNvVZV;ig-wYU-xg!rFTsjqBA>%olz8*;6`_`^<LiBhB)1H z?pr__p0i}`5AGtkFL-5jDkdVJ$v!!6^KpUZ>Ac!ct}YFzX{2`$8!!|<|I8Ft$qNx5 z`^~j%d)?kV3)gsS0bCozH*G3aXKiVp1_Lp{?QHJ04lXw<*Gb#!Z;?+jPHEc=F34th zcej?&*X~4Hd3ox{t2bD`H!Y^IyBNA4u%oRNl4Ayfe+VWnjru$QwjuT9+4&xq;;);C zhs8IHSr~{trYHYOrs;Pz4t5_G<f8uU%WFcEkGI_jz~5iD-j;OIlZm?ROmG`67Q|k7 zOl{D9yt^FA>rP3T1|vx3JX(xrYU;c<Qj3#m5lFQ%su02tMC}YO(?WJT#5-7pve}-< z$asF~tf2bKU77ABc7Xq%xz|l-tuL5X%1K*ST1r#>KRV^V(a4=BOCO_p#RE9q*$&G( z6uf5O&e9EHB|VszzZ~A-OKbY=5$D1cREu%Nn2R9d7S$0F`n5TNbE=wWKGM>najT$z zq>5)AI^y?*E7litFe?aMtRQlyZD~D!Pr5D0@Rj(PPmx1djwRQn?xkpi!-jUede%3a zcAlvc^Ty!Gw_t~jwgtnbQAhcD8hZ2abQ5A!%xHfq)wI=(qeE7&C3OE^&pZe|jWs2$ zXXN;<D6Dqds!wY-XIOB$rUuL&a?IXZy|uSzJkk_cyC$6Y;OoiX%qmqlP<haVKIlOd zE~eoI-ew|}{J!#osrx^d;_8$Wc}3BYzrgsp{6R8WzgU{{=5Q)4e&#b2-QV^=h;vb2 z9%+3cexOp1PH|8q=VAD-9z5NmTF6UNvlt)<+i~E%uLj}*|Fkn;=e4HdBz!Ez(UL2} z<&M?Q3%#k1{YfQ)h4R0;E3U$9<RakCS6zB!3GToB1@Jd-rRJ&I{sU63rIge{n8*7g zFFz{F%v_pbC@n?`U4B}$kUC6&zWsvLNn7-&Ae8@=DEV;x311{MhEMZ+q9IZ4KNCC8 zxkWPya#w&{c3I!m^(kbHl%>37rUEDGH$}3a`sifx*dcv?T8@$zr4a;#=>51fD@4Vb zpk+}B`b!l7(ba0f4$bmZOAIeyin3@`*WGJ5?`r4nT^f(Wxz~mi_dp7+i6MB$9(G>7 zfC4#~J~u7>p0AKq9S~`Bq3-jNYU8>$ub`K5H3b}xzNpQ`UuIn?Ih{JM_UP{L9b1yT z{_*c8DDqA7V}D#)WkX0|y;mw(v&=?Uk@oLT77%|cPq-dN%C(NRYDG4URQNfjB<ISG zrw%0=imdUxYC;?Y)aPeSh>grTeob3yL%5ij#e%F{sVQy)v$s63yK7UUPK?IJGaOu5 zQ`zPuJl`U5wnB1_K!1*gxSVpmAmf?h2;@0<77U0&fmB~Knx4$n{!|;X{AhIQw`nr} z&+b@D;?zru^f8??&_AjC)kq;d(;>oh7j=Dw=Jme`15$=!_A=URkiyiURl~IIYFQD9 ztP$FEsBr4wzbn;_nYRtN)044Z$z=u7eBC-*nkh9;6zr<P&%y9Iu$3kylE+%E5G{IJ zq{5ZloPJEx7a{UhB2+NvP9M?bls?Av{erEIm14(*67wT;gk9B@dKff?VPv_d`bUVe z5v&c+%(Z@e-Cwzk36esa{}bt@&L!&+n^y_Pa%20VxHAB7bmS=(biOXtJjcX+f6L6m zLnM2?iL?_^_0w>HWxm;fXp>kmAMk`B>sfHJ);y`14;Q)av0_o=v9pj}JYN%qC*o=y zN%1i@!9Ga=PmRl#Bg)-NyGzXLndd#lPx7;~V%c<0N%}oyXJM>fpCl*S+{%15>i^r1 zaVShZCOoLd@t<Xe$E89|$aM`_ILBe3sWuy|nPH0IeE+F%RV0Vvl~=%7U;C@)M*h#` zzHeSrrQ1lCN^#>^2Q^06s-D!96XRiS_UA2%kJPBy_?U?h@uoKV&B!+s3JquolC$!q zraZ~UH9uj0p2h%ltllw9$nC1OUi^k)N8Y@}c!S?qMz>x{YpCg1Be3=+hO7s`h8D0a zLdiM-!?9X{>7Q8@@?VO~5c+7IYgdcJt1Y%)cbB7GjGxSqo2;?Zs5!IeKmju<SdcIe zrnX=uG5GD=>68oC(63?h*tp)K>eF!2WBXKg3a;A6N<0dydsX3QT3%W}MKPwZcRfC& z(ky7I`nERu8uSDe;~Q`Lo{LB6r-k_#vuY8&b}4+;JS*e6Qv9zd8%4eTdtA<=9H;&= zsB~8LHs|`edS^4fl{S0>;fBuE9MnUY5n}@J>YX(;UtND;xR8hhBIg4x+<Yo7viO!g z_g=hv(+~W{*ktbt`yWvMQFve6b|31F?<uM*arzhN(X`Kk;CYw9f6TM^f^{-PrmBJ` zHpo62xCKmAR`(2iP;11IUo=gw*-7D~I#k691#bryWbIt9VS{F7Mwdts%-qEwU-t>2 znAf_xqW`=2#(Krbwl*8AxSQTk0VW?FNAA3pYC75LDmZLKM_;EM*qD}4M%!pFio+|? z+|9DTg3;GY&SpSWRlEz`tVF^S(YsRZtc?{fYtIERCQG-a07!H4>*xJm8+Y9I+4|ux zvqj-qeS@;P><Z_fdbH?a;9ccI(Rf+SG&F_HyW#et-o|>(l*VfyyT1>FyzRRIJI`Gf z#G03%Vh77FL>#HR;ec&p4NkA^iTZVudmt}bS7zx3=>6yzUdT&7p0hUy%y@ZA1YhMM zTj5My=t`GF_dvRJ2ksT3$-kGzq4#*+uKWCjrf>%_EaZo0Tm6-P^ted&mI#<2IwBk| zFP1R{E3;Qum*0%`34wqmFYw@{q^h)O+Y{-jX1UQ6RMcgjoVM|L=)hRooikM`@i_{S zJ`<C(ly1V1yRuFE!%UbXY17sp_ItUC$i8xivPmDOf1dc|Ih>xwCn%6?^Idw3qub5F z+f0u&>-ARH<~-wtb<Ik7UXds30-Uiv=X|zX{p9yy%gpqqYw|-L9<rONtFhsO(Z&XB zb;Q6yOG<irdzE_x{gImx7MWaI?qFKN4!b={c~KPxc9Q2Ml<ytkS*|kO<r&={exs=w z>`Nm>-mo)21lO9tzCm0uTLhu!r9$r6K{7rTkJ+h96-6)|>-`Q7Pl)x`J0-xOUkCap zBwCzAqVa+3Yus<SVk9SW5Ya{^l26Z0WY?I!0jhwJhB-QZTGm5qQOAh7{rO|RQ9sAc zP%GUj2#U%FK9?0yL$Ll)a$(@=YTpt+yiZQf-Ce)Ql#|Wpqx$LH<-($^Vp%62@L=6y z{vL6p=))G9@*cOOHI26Z^#uC0Q0lyAEFwt&aN3L^Vw67clV>6KZdXdDMckxl6OZmD z7oT)ueNT*(r#9flk;q|CP5sqq@<{D7sCGYWIkJ@Kh~r1auPVth9Dz!tUZUAhZ=BX9 z!R6uYr7cyJDXPBbo{6?8+r#w0JEKMG?CZ~)`A(;-bOtsCB<PMQ^ce9;9(NvK9YUle z3J0(+IqF!Ck~8v|!B$xGFKTp~fi2M32-{hWnw*KI0qG7)3(?mN4f)ZFUWk<&bXr?% z{Xjmz3vnCpIeF@D-c>sL81(gl2a{U)8ZP^9i$5$OcZ%)!G>h+n4?Wg-q4Nx7V-8Ng znuUI{Z+0?yIv5Egac+j!ZeJF*OK9V^RY!H8+$MXy*qx_LY`i<2)D+h=KA0xPb;{LM z!4Bc=Y^>5KLlp3-gIFn9mYrL3j?xxyu>tG-R$FC337FX2?ONPKPa=jkjMXt~muohu zU;r)E!Nd9lQZ0me2Yz1^NqR?PpGbHR>E7FF2><qu<g;4ixcQ(l9MuM1cULcSi;6~l z=FBgAr0l>N%hB-6zX7iHg}V7^%<H*dzg?Z4`mndtUtTw3-jM2^zb~#@&Hz4q?$>$5 zYw}t!c-=}%N=r7@m}b`UQjXjX5o5o(Z^He~!I2=lFjd2o_VpFec&WWxIzhP9(9w+4 zBMX`EBf~PhG%#p8sW)5*7x>{(jkeCR;s1@;2-f{FHhMqD&3Qt)qqMcO<;3geCGU9M z<9apDt+vJ1W#aF-twGE2{>%FC=mrPiX8&o{DgQFXpiL{9QTo{B>~jA8$gvhp$)1^^ zp8CoEy<eSQgYxj@m7+`K0WaEn3@ZmC6C}LxMYp7~d!|+_0n>czly{Qrx}k&PX6>sM zOw&(<Hnugd8#Cv_pmU{ppI@LxXx%JtZ|by!%~;_=*tMZ_bH#>;{*aTq!O)rOLl!o9 z`4Ombyg3~p|E6>}zPhAR8?hsJQi<m2_*IO;|C(E%D_8>Q1Xlk!|Ede)+dJqI78b!r z<Fr>}+TYZKk6Uzb)ta?nBoMohI#4VM3(#@3$@{)`9nl%%6`Yu<$$k}jB)K&q6>$xg z5`XJic!L334@8(fv;v8ZI@=rxm!~Qcdy*nMMCN2(SgNsn>A%Y4_62u4nQLb0wmy>1 zuIaT3xp1c83?Z*hCXH`kj(0pQItYH8rc{P%Kb<|a65IA~0aR%_t9O$ZU`cv;P>%;A z3#QD63J_(*Mw12Er#F8vNcz%SVsF(EL>I&=Id|HluVw08$2yzo%GX-_m^|1`v3EQ9 z@($Ou(H%Sat>2;Na&!G<^YYMI(sj+688W2iYgbc$Je=CzRb`7C<*Ac++nGt|)~#S3 zzEM-0C~VnWsCegKXLn$7Ds=d^wDI$8Ope{sW<e;oW2*3Ms#<7A`pL=7DsUSsl1?{3 zG2fgeFrMw=n6Uk$QkJKUP=XoDiX-R2v}K@T*tWHqD?yR9$II&(&P<~fN;+DvyedW0 zn%SP9XkUWGS<`w&%22AGLJFo)SPwcXx%g`?3opVy@sz}$+&4u$XvtLlwvjVT3zQ)E zfLt>AG-m|JT4NMc2Fra=<5Y4v?c1TC+q<Dy65zw0dT_M|azR*G+U!?E1yq3@zgUOi zz;*P|M?t9PT(H5Swn6Jo<67T52)XFjVzK?*&Q|ZMqa~eeHLB=S7C=XHSM$-do`%Qd z<jS&~T&~LAm;3M1Hlw+d$bE?z&-WEwt*{|kL+q3v#bYYiTkwGx1dq2e(Rz8+^KNP| zvOg#s8&L{EWlhyPL5HKuoHT?;1hGjnYCHbpsX3N(rbB8-Fz5pmPV1-P3)65V)s8ea zU=Mgty$c>YyIm}D@D?jx?OZ;Q?yrfDEy%s>w2*1BVTj!mXn5Le_4*`N{C-!j)}h^Q z+N$7n)q4f9Ghcr`lsORa*hm(xRvB+sDSAhTYFe>-!EoAqE+xkD4<QvyYybvaVQEor z1qL$Ft0EF=FH0bj^iEh!+^^xx`A768qCXp&W*rh<5H{y?WvqnvbTnQvVjhcVH^3sY zLbnWs_8%eei{&OGa%F5RP%GJ4(<h7|5R}CVWkEBP@2JiS$J^<D36~^GuzeIy-kf<k ziD@ctP8w*>WN`g>6lk)1i5M<5M_#f5s(zu<hP+qTfA6JPoT6AadNIJqpse$V>76eF z)fssT1@@TG+{~O}3&0=v)%il@&wr~Ou`4WvQ!|^)|3Z!S`qy&5F8!BO5(y9nvxNGx z?MXFZGgHa=!u8=^v)%5wb*&}Q>T^T<q>B-}?XknO?NHvBU4jX6W{MAv#X0#AA8*%p z=o$WdJ+2RhxMm5(f(0!utLqgQ*<^|_#X_4n3iTAmHiKf;U1fdKZXK@60@e&0Alhq? zRvF5RNB^cDk4ukcV}}k0a{;CHgMr)DUU))a6h4hjd5U&0*$WB{k1qRDad<-a0G1{7 zp>Xp&wadlook^4Ftx3XcF?{``_LXokku_@~zE^YCRe6D@7Kh~%$Fdt7zs&rWhhvG< zvQ|qe_0GTb8lDB09o#Qb$eNOeFYf&|=MIdGI|J{MSNQ3g84~jo7*@ni|8Q6)i%qgI zpqehUo*GUXbXtCuC;B%`7=5Rgj?|d}NvMgW)PDJe$gF4mm}su4A0PjTjk+b4$7^aG z`PeTr<8qzH_79tFs{n_nvVVMBX)U0DI&fpD1lg{Ez2;)`8ubf+k4Kr(Q<#TBrE~oC z+v|1(TjRp)%0EI4t_!Wp>r;}~5>EI(#JH4d$-`CUsB#1}BZ@N#b~eU@k+iyU4#tW{ zD-RE+O(}GGj#b71@A*T8&ijf>E6+?%y!h{HPf6LyV2?~aA-!pZ1;&eG=^(Y8Jy_rR zZyCU7`ud3dgYyJ3Hw#AiyF_V^aLgM{U}3B2mkgXXCTI#PodXGigT1!m!0HZD09b5? z<;=<a_*B~XXe+NT6hLdt_+V$W(KTJY{lu3A2^e0n<Bqx$8auOHlS7Gm3GL(O7#-q* zTmmQ%M>t9HM;!`tLs=GmMdhcQsTDk5?N=E7YMmfc6WL!9FN{y`o+T#@9egjVz!jCg z2pY26nA6P@ts_F|P(7yAz-w-NY9N1oO7aSZ6|7aLGCWY3MFwT|-&uYXI%#eqY;H(a z8rUfjYOD<@9^fSP%Qx23EKcENoop<RwR1wz8k5}ct^&^Wv(9t5B9iYA+;M3iQrykl z-UB|h&3F!j{Z>Zn2AI2<^I^k;N~%Ll!i$*?;bQ5g7J?Q1^VHTbF_f^Be`ImK+zrEY zcEBfveF97#NguS-6m9BLGv~fsKYXq0E*blbuh|ZTJp#uEl4Q@NT>Hc2;KgQ!TeG!@ z{=eC#)T6S+qN?-(7yo_xnlibR7E~9RKrDb{$?{1wCD&YIO*l90D<=cV2?gF7tO-mC z)OV)hBlVo2Wv)M({*r@&*QuO90O(<ZQo38>QtPMG&*`YS#{PCM3hW|4*Z~0RBtMH! zh5MsBzbdUwaa1WOkv9I|177Ty%i+_dpO;I|8X245`cSS`x*p!SB6Nabmz3CS!5;lT z@|SMX&!!Aa5i;#<`g$|or6`C{H*?=z&FvK=I40-3&ivM=N_iVaF8<jf<~$VKv{H>d zYquSN`KTaZ*O#wYwW_uhMnT?msy{6Zom;P?-2{y5!HA9E@03xI@1e6OPf1H=PK3G_ z2M#F-Tt8mJwun_&bl@AHv+#1Q)zc_hGdza#q!_x+=4vuc#vpc{zdGk3&F(!PuV9~0 z(`iQ<p+G@CGy%721+{dwjF-}?r!~hmce>T)9>+E+l2=W|qH%N0>?6u*JlLt|8|+kG zEk4u=;5k>}61*|(oa$CzA7W?l?X9tcHcO+osw`*g$Yd3APvW=d@zqOjC^tSryMy5w z`ex2j{L&<10nccxjpkd<>#jfR&I&pIY)G+6QXGY4R*V@%w(XQM6DNc(bGZ10?fjZ} zmw9Pvl2nsW3$Nz&|6KUJ^}@Ml|CM}b(lT!IEtcw5v-!bG?>%@3Q!htn9kNh2)*Ism zzqgfPtHs^mxkXnv5>C|Bx&h6-Q2K!l1`QxbJ97gx{N~SiRINy=Yfa>dX|(D(#G&Sn zP!~3waJ`k@oTT0TsR1Fd<|j576skyeHXy<TT7H<<RW)xrA7LR@*fijwF8jkj$86Js zK{IDFIuswbr{AOViL9+0h_uv;sl)S@XVYjDk!*+v`0A52c?hy>R|sa!B6}2-A(rmM z2sA_^D49>IY)rAc!!+S`+$%O09)&8H>7-2;n>;t2N0NGr)@!<YHiahcKr*Br7eCIH zCtA72FBhvfbcsH4?8bI&&q&q_r8Ektu#`~a8a2)*DU{mr*#siz1<k@mJ3?rrvvrOM zq~IEnz#88FuLW=tK*SrnyJ%~%HCoxod|EHKIVn(GOdHpQoZFkA3+Dk}O3R9GUZ0~} z5qa<sxB-o&N+z}5yvh-mge@Cn!f!s<LlRcUp)ix&yL1hU5!}=K3|dBJXgzt9iBW`| zUR?oEwfY{tEg=wT@zMrLj&?yaV8*LCfv(NkqIit9VD4UnTKLzf@RxjCj^L3Bd6~4; zU-R~!Ef`MS@36Nbw@SOv1Xu9JHtQ@L&U{30AuCv(>C;|&7O?mdbWK~WNM8*`9C8|9 z1`_EMf@utLTCT^>ot$S}T5UOVF2-$%M)F%wcB+_4745u1v~CZtEKzr(;RWFM=;D+F zi*NYQa$|UfJ0V<QcFm!q@mVjs!~4eu+YHSoCi>&O#jXp2amBqy>|0?CX=zr_-4DH9 z1FDN}lye(b9d<a}8s-|bau<jk8i=j@ZQKi^)^<i8Ya<hM>94a+ZdbD5canp5$7Bm1 zq*^mv1!$TwFpkk-M22VY0&wEw1obs~hlASn<iG4=@1=ktsCksy$y(aJwbYK1uH!@a z>lsALx3z0*36mYnPf82?1uh?ItWENWPy^v{^vddsqXj>ka`hD$>Q9XkqLkEAoYJ%T zPo~TxDf|nKEEFouaf;d_F^w2;o(o**mYuRVso_*PA{LIk{3X!p<fAY35*C6y$Q}G7 z2R)Irvu(ado_2T~H3zD$RH#yioy_@F*gRg|UHDGDe%nlN;;J-<675<vo9x=-O10B& zOXc9-a-*{I$kCyTJ=ExQazh0EmZdBfyZOWg-{OA%*0XfLHYfXBfd0&1;NhAt?`=yv zx5qc-kOu>)^naQ*0z%N_mpOgiE>D;pQI%4orm13{BFTSaNdF97$<a3)(l)De5FyO| z7jZ)tXC~en8jI=l{RCH#z!i43ER62)@Q3uazf5^g{wWNo^uHsQni%VNzA7Hx)>Tfe z7qRl@n`HWYf!Bf2lFqz{MkQ9lnuw9+&|Krx{ps^@7D*S0^zk|$U4fjYUtB)UFE$JB z7A-0=$%x@kZz-=0kv7H|i%NnU85<1r$wxdPJ>!X{v3WWeR?tPx<ukcQESbc)^XJm3 zjYAsQp9=dNtb4n9|C%FN*<j1Z=__&N9yffq@^{*rc5=@-b8P3<`oFWi3Jz4vN-wAN z%HLug(P<)s1slKI+3jpLiBLL?+QHH#pX=eKF%uSsqvI~?592nQpWZOYQ0f~PLsLxJ zxIp>lRAl~X^$3FR=3qlf6FvNJyk0pfaI*a|g#3&i4vSc*O51JZ=3JW^Lk#U7>1v;D z(YZHsQl~&mN3-#nb1Ypb9;f}2UQ+V(M;@!OkT2l<GKRrFqp117%ICtFRt`Xmh+U)^ z2!Frs26@n#tn`ZCZ;J_Cv{mO$SnJ+%XOnT`sWpu`wcEb>Ljxm)FErLNuUdiYsu=cS zbY$te+P*XS>iLc5gLl@p;twr!8D6~BgSgbJ5tA=7YioNZXGtyTe?N>QBN)@QQ~dMY z%^}aZ$%4vFFLTnY6gQdBrM*+do*aeFY}y`GN{c|jCfhooRs7@EJjw4x7FaLTkj|A| ziX~?Gy#W0Sn7iSXv31Jz`hzh(4ju62ktCBEnM^q5>SQC54gRG05vO%C0pZiK;VQqB zu%vFII?8qr_DQLovoVUwu`*xTh(x$#-u*eG*_qKQvBAxW+H2VR%*YdLx9F4)g|Vj& z8LLuJh*uHXErVvic4LGs{arEFWvv%5)%hogSQsNUiNS|BO`ac6-aC^IUjegX+Lgl1 z(-s1hr>ONfxEXxU%y_r2NJ>MRE$@cZY9j|K`#RBs*fzEl@V3j&5ft$CnVY;{UMH2N z?YkKO(xQmTgnk|;drh`C;q0E~TlY;0-Mf;|1=J&w!|xTZIn}Se5l5t0R$p>_-cJ`q z6j}S7_ZuiL_GFZ?&>dea2{TeNtw${zPOLKGd&-+DMe;+?e>t5M7Dz&GAx2RT%m|CG zsnmR38#O7BRqdeE!N%&9nErgH#HeYvOycbK+%hr`cdWAc_Htg5uAcEEJd^M);h+t~ zy?^-It*44AS$sm*Br7qJvvkDW)k)N?M!i6`Xi|)EI>!l6#nvmyC5&uf;&WB*0f`ZD z-HjG360rtOzA&{F8{}PAoIA~9`<2=dj3*uFwYOLer*4Lc0UYyzCz=;(p`=tT#eY}C zO+QuOr#0BSah0h;1?aHdq!A+|NfJQzlYMXY=d@IO@eV-W_bQ3|HFd;X^(3Ql1?f+g zY2|F`oA@)pzagOo_oaTikyZuE^B$d8uc#Eh;yl9rPQ!3%ir3gevfJ1RL2^@PW8ruU z#_L+;-=<=>XFV*o3X+^7o;S|gkyXoV5xA5uZUeJoEnZTz=2P*z)4TRDB9{nzBPTL) zO8QzRRF89&!*cC|HXD~+sz2~%Z@6I3iLqKwu;7d(Ws*axlXLXBpCVi@wnx}@k^bKo zp^W6EE?K<SKGAW#ZQF$3^|JK8Z;SR6>$I}ht)2bc1Bq~Jbv*SpR!R<3OtJ>_*NT7t zb+K*y-Noc1re4g>^rCSeiBLdv61w`X?G9DB!SW9Y@&V<@Y0E3z<vVuNku7B9l3T(4 zcgoXiM{7@LePX9pAjI)9ptb1Te>KK<&MJ_GU%!Q$La{R9egX}fMaGeSu1iLaqPCr1 zS;K4?-GAuog~kKUwC2cPHOmEBHoK0%wyHebMe>$zbA0mp2UUMl^!ztpKzJvdMe?W@ zc2WKf-A^OJ2*L8(pY7)k)AX}*mgBp3A|i>A$4sm{T$1#iUMl1+cmF=E)I2>MoDOr3 zD$mKRL$FGBA#L1d7@8?f@UT#Yw%xF)bYkNNaely(1vG_9+}#cAiO3?iWd|@~C?z#E zZ{HDbOkhD&TeFBG7ARVT&&OdA{BxlWDA1EDt_qM_jL)le4*=NeJS3he2{g$~PsirL z;z76GaGh#pQyAF<TGYOyw*$E-4@Y)MeoE_)siEOEGX%f*mhTNrVppqcUz%nN4py7n zq9v=T`z}e!+ZS`L&c*R)r+T%rD*j#k$8vkF`~46Uz1L5bu9M<lqRF-^8O<LIth34x z9YuuE;-sUsIAb67{FUs4-ff+;XJ;*Z1ZwoHcUbk#4>dwoWZZ(vCIn*4iGBh8lD`RH z`6(b+-9>QF=kE*5wg`;a3)=j&17GQiU6dBu;^gCBIYSE9c7!iM4uh^5LLmOJ%ln-v zw%|LM_=m6*bFcKC+!?ndKXyrAnYLK{k}nf=t(+As@HpVxWY*9}NyGM!>aBqHr&`$% z?I!};e*HjqG#%~c?2*__79>rkGmQf+&9jUdQuf+x;Gex~kBzIJeHlVyh`8zV2Cgb~ z>W{N*#)kMQdZ4`^3PF#EKv_I)sT|MG%jj$wK`wYR?nj^#0Wg+!woYv4g?n(KgPEQ% z(ZZKY_H`ruZpys*Q5KkB(s<adN-WcCIZb8B#Wkke{Q;oYgtNaU6Kne94Dk55Z7t7h zy&l##Py-E^fG#M@U%mdM#MU*_HIa{0O&o_R&KXBxO<GfQtHqhQt+Xc`5Jx409kL3S z*Cx(<Bx){_@v7o}23F?L;W_}wLZe*LmD|r_UEb6Uau35D?|wgm0p-P@6|-%g1X&3d z%gbX>dMTQ<Ae;8V>~rxq=^od4@OM+IR$%919Oo_jWlIyl0I?6UA#r2_0-I|3EK6ut z()}c~V$XRfZ1rIw_qVWs09EC9mx5PcG_?Q>hEsr~M3)i8LJT$APMJv6ew_#%e&d9m z^DTfZsOnO9&s4x1w&lK7N^ZSN8F-j$BCJ(7WZ(z+sSMDu<Yk3iTnV>cZj!V3dtPA7 zDwL<)t4<u!ENZ=TEx@Q9%SbUL?Gn^uEeL7AzX?zez<W%-*`&Uo3jrQ2n4Ni&@H!E9 zq(6Fqp+<5a2G(%nl~~#HUv+e)5aFMvn{|)=eYfli!gy||@cZ-FGOHGdkuNc6D=Z$} z30rbxPd3N=v?H4V<vYS)j?j==61m!Tk!mSjSBIbRI}a0pIhJ$hC%!&&2|CMnTk`0d zOxZ@(h|evD-zYAX<bvIEPjw4Gn%(8O0YT98fY4Lh5l^mYiONC=Y9T`6H3NH9@JUVT zdu0YZ5_glQ4Y&a*4~xbmh2P&7qc0`8-oQfzB;A0vDEB`NcfQMBqi#fx3hsCI+E{Q! zq8?9nz&8>0Rbjp9;XDfD*CVsz-D`W$l-;U|<o+4`jP>M`co@GX_OGwvxaEPwC2JIN zUE#p(lB2a7BSMO+@nawa@VVRV_PLg>G6`HZtL99;kC%_bLH8F*u{cGp%DAx@2OeWW zqIP01D3|q%(su$Y3m#J`$EvW^Vi>5?V?yw=BOq%@PK*Xm^6*LN{yAnf+lRgl7IEZG zIk{{!rG{Mm8}zvFK%d(cdpgrqN*%PK`nrpz4upMTBRQ0yE90;XQwY0cc0fb9>6UrW zcgiUFbKd-v@Vu2-teyQ$C$F)zV-MzzHv?(*KW5YC)XbigBh4%0$MG>o6BBmR=LF&v z@2)~H)F-Pls~@Y=s1c^H+B<&Yv(FgDV;C0AqbBTsZ%X0RDpcb+op)c{uZt^A{zhm3 zSmP%>W}02{19q~a6<yNoau`vmBWfr${TE<4Nf7@2V&X_jl<Gm_FcsYy)<kmp*Wb5A zj|l*ov)nz!p%$a2?Ls4%$2m)+9Y}BCFmjBDe-l0XJxehqX}BTV-zo;lrwMHui*UyS zk+cAvnfY+K^e3Q=?Ze<j0sdCUsIDdJrjt1?*3kJmy);%`(Us{j5{$?R9DnGu(xZ|f zOMW|YI-CSDHH(E^H5dWJ=K8<`2W$bX-2u;NdVP_}Z>_c8T(&q%#&FZ6of`pAzV*l& z1Vv#br2{6LsdWM~u;1V$)hYZBDricS%Mux_EL1ZwurO~6dJc#0B4Q=;x~0e#kxQ0y z$Fpkdk!BaF_->l$WAR)MTqo{V;9yZ9DZJAW3D9%h05i^M%*ZBkH{#6g)v+dd6A4p- zhpO!y8kNNa#4^oU{yMG^12t~faA2K?tcJn*caqOz-_k(UdjMKXtgpOlDB%WA+1Ov| zv*lbn^k^z^J@t%dGA=u^mTLQ1>X|!2#*B)+*Q(J#9U}Fo^m>J<VS5ma|0e@0jxh@D zcnXa6Bo%~rq+L4eyr+k$W`59j?4r;V9+cOf-iLKN?G5FQ1S#WJ)fl|#z`Q=B%b9${ zh}bc-+6X6$SQPQ(je2vRxL?8U0WmtRY>1VQ2nLSpaeX*Nxf$nzzO|(uhn)vNoAiTv zWU^Z=D#x`3D<3}Z0P3+X>FO!#MN}ACjEhBXiiI+Yan+%9967!~sFth#1ncR;W>?AM zjIxeD?jx(<J@Y-SDajk_<1?rAoC(&Zg(_K=I1V1k(k~ULw|~1l9#;EW_%klGvw@y0 z47HU+J|6d3F6*pLn=Yb`e;V1%C_(k|em<NZFlEdo<xqx=M@mJzzWr_i(2<#JW~!{% zy$_a(IHsytdiCl;IWP^z9`H5Af5+`#TdMT~*3*VRv?STzgPIDgx}UD`<6|MoKPH4! z0<|U7Z)Viq9fDG>7%4l~R^m8FKW6>)3@Pb}C9COq1y_SW4S#l#Zt31GunU}RYgi<x zw^-}7vfCr>QVUx6Wd=RlTu*Nm|JdR$e{iihzI8-9E4b0ECZK1ga6!}2$iRkHD-WV( z8;*-2%>TP$v5(EP^3N0dk_KtjPp)C|;Pr}i{2(D`CRrDG&i=ISbgz4zP)>v=df2nn zo|ORAE|l1^60p;^`*s7%dZ^@INYPerHvJ840*y~>w2mOXS-wzZ^ZIuPtI@ph);rlH zMGLU}2WN7KM%{&)@7K9t#~`?hOOE9_AWPXEOakDh6Yf}e8;0dGxASwcA6J9+&7qpj zWs)Osf%u&qSSj7Jk?zs5_lbM9+{vE_UP=-CfJ*`8yQ_<n-~I2cUow_<`}E<LI23y| z_a|gFJ2cw-QDo!R3oXYSw8biy?TTS*zD?iD5!*qE^j|VIN+3u*D4bFz-AO@5AfPav zdjt};nw|t%hgj$)FKYY@FWnv-&4&Kfc%HJIk6V~L-~1AZPRoAi!xq)6%%}>NN(^8b zaGd<W@`Hq3t<Fs1F|{q93g?GHZb~IlRED?3CWM;tabaeAJZU>x{pMU#ucR3$OY{av zrlo5Tniuq@fR2N#{h+<)y8|t^3K;91va~of-_bw=!e-=>Dk_&a1^-nJqn<ZfiXSX~ zLw>t4&01_=>L{lp$NxA#u^}V5rG~LgQac-&oAZ+hA^S<&7Fxt%z5E#{+}318t0k&x ztZ|~^s%|lu-pXdc@J;?<GzIsGnUDn@vs{B-8mKx7lZczy#J|S<-(kP61Xp?+G4nlc zwf~jeXK94a;(U&>t6_#yaAS$3wRG!Trag0^5NOTNxf-P?tG}^ZYhf?esQ+Ciy!Chq zn447WM&r8q<K^RcyhI|TZ`mL8&7F7dPDNF6H(I1yDIaR&uE+%wL+g1`_BbPnB$-}2 zh0{7|BrlDgoidfolmPp1_+WV@lR(hYi<!<)6xIA9R+bh@@W4olSzv2I{CZ!nCp5ht z#&W&9Y4g{@yl!Yav}Cy;GTsO>fL4wTF)HI7cwyZG&&!;O_t^F>?LtH`oVw!6=e<XL zDYyl(!i9lBUMQOO(ki5A$xCnNzY|_>+Z?>r7iK4ZhKAKZwl5!jT=M*0prTjSQIK@( zIvXiqw2dgzlUe*Gcp-CO>yp2+qb)_bb$i?wQAE{6?su0wk+-cRLzf;zrl2`C{c~(3 z7EHS?iZpMw;omC(5C=9d&-@lN{<24=RSB?Ke07$OW1>vj-PMt2N(vb<TYE9HLEvqA zSnq{9rr5j+HGQ!qSbngD00|Mn;juh^dJ-PXV_e<`5+q7dWIiS_BWHj8GEakbrqC7F z`Re|S!p_s~uTIfHnJUbj035mo3SDQ-!%wL3cr5;5;x=kyTU|~Mk3$v1&Y-d!ROdTw zB$(GoV(8eL6%1i0RCJrFNoMBE8E<=D6eWVlNz6KPzW|JxhK6$l3_{jYY8iAW^y-!m zwdK?%+jrQ1T{pPG%o2_h=^9d(g^iKt+HS?#W@v6zpz-|&bSV1idsFX?L%al~3a7Qu zxh0I7x$T|-$pZ}RqLW_3!Yp*MW<S5RwUzganAJ@p6z98Nmbj2=;xSyc1A1bVK*+>s znGZ5D`65`xNuo&Ro64qC11C_lA&QStnn=I`s2{OJx-nJV7buw^VT&HqwUpN%fZPeu z5$+EOfvQe&0f<Hp0zD*h=zk@#l|R4#C3TKW2i@5jodu?aWXuQCwL#k!sag`;BIuMv zjRS6)vS);yOz!y=F@6DI*p8N2W_MxkAQQZVrQ>Nb8tkH>)F=1L#iPPrHE*-alGn)& z!Xf0>U=rbdbSSJ6k;m1P!p)<lykULHtub?Xf7~-6b`*Y`@Yrz0k-jwgKiD&1cWJ`} zye#>fzvIK5miw8}b`8vxyV8h&TCx>3gCeW3khR_SKu6j8zed6C)1-SzYfjqinm_~| z=stIuJI*s=3q1uH-x;dI`kxzl;-P83Cx33HY=ct$=AVBhyM0UhTHKJ=3Xdl&GpZKX zuSm%=ozPM&Y^`Do6xfCV-9YmG53{%@B4p4V)$pQ~F(M(?3o|#%%@?KA#XrdlKGtxK zqD(5=W(qeGVGH9uX<JS2BI0T|D6CI3%V)uGTNu<xo4GDiGu`&04qjfm+;5(2ac<fn z8I!HT&n5%*pRXbZ``i(+Ec2U6CG8}-`@umuOlt~qp?C*<3k9$1g?KUZPN+_UhvKzf z1h^Nw-qxwUwXV1^h0x-uoiD-~+-xc8g4qzw`haYjU~?idjfIlpVl#h+xK?(*?*Jh4 z%r<4I$B0*3C!mAt;j5>|eqq&d2CP`1B#{X;4Z;B|6i}1RauWRwX(6W+F99!hD6bzr zVqugdldZvdR?zx;qD7aVg&=}m0MjISdK&Zha-3=mcUevs%N}c#?JC7m?3CclO~_8k z3w)MEP8!`pO2vrO{jHx4Vf8WD8nE;GJmssTL>VVlBcdOP4DyO+n%N^P4FtY_HNATN zX#DZ$tB~iyd4qf;4;oF7N$u!D_yCY^&O>`+To>}-%8VUqIsrb(o>=WHH;QV-s`9jm z$L_4AVGT!)%mfY0(1-V4a%0@!^gIldrpzKKqB$FF4NQuac}mJHCkYVFdi1%R3#SKO z@83m4FX9<T8mQZ?D#g&?dRS56m}11g9BC0Z6?yZ+X5Qyqv@1s5g)n|qjO0{LZ~xF= zg;;)usV?`g;mOP(Hr33UhR7VT2LRnI(g`7{Ni*KA56;4#)ZP#G6Cu}|(gy@5y)A$9 z-3H^Q@bNz3b920*#~*)}LCpBlTEH+C82sY6cvmcg^N5bvqH&T^?A7A2e=)WK@+n~# zGkpHsvc2&G`=y}iY{{=W-Y#C109f%e;C(qL^wJ5JIcR)#Jbz}+oDu$bcqV_YUN(>1 zP%W-Gi4ctu>$6~=uuMsY#nI|p5lrMH(4dLe1KL7&;um+-flZU*4kQkZw@@Ro02pK3 z|C|3IDe3)eYPB=()9~k}#FV$IAycwJe8V=ciOgM&utwUMTB-n8gB44HZWT5vJ2^pF zL_j0W3X_StAB(}<|5UHqWJ@{if8&5#mx}qj1h)&UR->m%;U@EW^_DhZ6*I!<^b|RG zTv?WF;IT--&0v9B9BTQ%OIW?}3aIy&-GqNCO^*s{+|<nH{~P<CKnknaCjJQ2b^8j# zr!KKe4+t=rP>)>ZhhD%N5k8YFT%R})?-2iFx(0<zvSsA@ZlYqC;G36w>@N#F#pmD< z@)b(mNQ(DM<cnT=d1Y}uy?yNsQA6ZO8a^FkKO*tmwJeqoS~|{!^e)sW8OfX6$<p&q z#BN6%8171ImV2Kv?q%UnyZ&{Fh`(6}?|z3q_SnmG9!G?;oTGIu!YDLX7cgvtwXIdC z8~Wg%0B%f$^}`*Lg(A(m{s(HGFBYB0E~55>y=&>>R1-z9A&9o!e9_Hj>is2OH1KH% zWMVV!Z#ev^NGj)bI+{>Jm{Q1atYHI*Inv1uv}b2--C_`J+EDW~U$hF9gdBfr?_aP( z@u*I?e;FEej%h}PC0-4~-yR5^nN5<`@*A;2{7`zWz^Q;a{d45UO+5N%f`6=*Can6L ziaf<azNuIqk==VQ`e!VTo*OFgdUo{csNHejovXUrF#ieZ*$gz_nmi;T&9<UL7$ILs zsIfd2STDT3LkhyJb|)Kzj}j?J9)TdT2HqyFHB;;N6vr(2%V!>RIdv)QB#bDx3Lefa z|Cw>*Go%EZ>feL+<JlVv+Ss%ew3OALMviolLUl#nz<+(N^J+p3QLuK|=t(S~$*P*L zRuiz?YK~Hf+Y+gC1X5~dreTwq<UDeKLNl`}{e&<<E*W6M;XgkV*qnIeFM*MD6132F zlu@e4FqeBM16Sqfmx_;z0nd$Hl-Jy)dm?eru(c325`p`=SGwVAE8DT^&O)QWt26Ql z=q}2QXnbif@d<So<!bmLPahVbD;wWmP7PmZDy}sh-{KCd^}96STyiN(3KW5dJI!FQ zhPe<o90|jZiqfj46H*%ndlE#GlcHCOyz(td#={IZGMPhkHen~f>)Hx)X$D*{6sU!S zNK63gzMhBtyEp#WT0C8Cf#RGCu)C-Rm}NBLB5;m4?kiGEBF-0<y~m=J+psTVelqy4 zgoTXlA$6dS`)k%_%95cRXbRCTr#+(5`k5C)jLk^_$=45mY@pTRxwhAS)$1@joa|{3 zbHElIIde|QEk$K!Chi=Uh54UhujFA{%DH~<sa;kHMS!<C$@tThu&<KFJQ{^qZ0Em5 z5>VtUy%q&BjV7DE{TYK&en6h*dQ7Dx3(Tyco)8lrmEr@w6At^O5pBGhES{}f-VHB9 zN@@P0g)EHoL1WKLzh>)F@dEQ4oQ2^237mu9b56T-Mb=H~{pjk|{L(22Nh}_<Z#UQ6 zwE6olgL;uxd_(*A*}UZ*%mA9Nhw5-Dloi){($Wdxl7Bw|+u7nG<{~W00(g^;&VWeD ztC^D0=c)+o3Jp^x9Ex?s3!MQcq7*<O`0OA%AvXr_?QBE|a&hCxEQ@9~|Go3%jXr@a zLVf6PU_`+bVz+U<1%fx%R`BO)!J&~m_&JS92S0ZNl=CJLHx}eh7r*DozGum87MlOi zj`9>nS-y^&@#Fl|-pt)2y{LZ`?RS8<@kB`T#Wd6M7^v<gliyGfN0t>Pq)$z7M@zi& zV20JfY>Z~6cQ?~HeN<1?rLuW?{M!odvu@T?OKn>z-^!j*yy`qe`qoq;UPVa{;nWH# z`G9!JI!ZsVzDTDQ34i!`9t_`KbN<vRd~=xQDp7<9kUrMYkXSK)j%0Q_d+UWP9Kz5q z4a(+C2;&*!Zh9c*`(Dxwf_62n-N4v_0bTb6j4nhC0NOWPPA0wEkY)|7v5WMUtIF=7 zc)oTQeQ1BPRC3y|zGDUCA{+gFETj}QTgiDvX_@~g)-w?~IL9C@bFK}fs;60rd+HuK z*p40EnVFpFUdnV(c%wucL{M%-3DlU1rtZpzx6#8L?XvRDz^a@XwO$q&c{sL{`(egw zPl$bc)|2fIOK!aSS@wn=fliAd9lDcFlyP6Sk{0pR=E1C1S8cM(oO?{1M)vvYQJMMN z?eYwb7((jw3^WI6XH(#9&VQPNJN8|NJ3eJF8~pspHL5P_#i`%$Cu?wFn0$CV;qaQL z`2TAGPDEzBjcS^<m`TMc%r#|p{OAANgc66Pv?y(yXzA3i3zmPaH^FF8pvhn(#}`K| z)b(9NfvOF{s}r@tb!ScBkTaim-mFSFCT+@ieMF=cNUqaTB*YscEM${7Q$p&!#4i_4 zC{O!g^&24`Rz%EELk=#liyEK0+g|c>S)g67l_m0(lg;xggLY}=NSh}N{x``ya!P8? zPh`ykkDHG?cFEChLab>ABR6ytDoMQYrzX055Fl!8ZG3Zhv~u=+vOs%(DYpGgEBCh0 z_cK5zN~sfZKns72+W$8()ITBEsb7py)1#DE?mLW<Y6B15bA4)kMw7fbe?Pes#gDFh z7@tT#ER~dOs-)gcSy6d)PEJOCOAE@BGIn7xcEm$TtH9(RHu|eW`)!k-H^Gk<@CgTi zY(8~dCvzmI&6;!0n!T-(bFRQdz{cLRp<Re`T;~?K%b;#&FRuajkYQO_;4Pv;a#cXZ zflO!{gaJh?uc<~O%9bK3@ZfQ|94Kt>|H?a!syLFZSPQ=aM@8<~xRhLhsgqiP$@^bc zhBv`38oBIq+%VS4z7|xw%utlggEhNV9vRY?XV9W+j|_>cD`zGmNMA2Bv2rz3^neh` z{xT;DlD;VpXwD$`_K{Qtl!KWR?NmulQLBLUxZwy%s6B$)6iJe)2|9ar!A`jX)S#AU zJr8H7`(2mLhEu59!qyx>LU8;Jf4+L)-ZRzjd8z-{$C(7U<jU{*?JZxG8$UZ6p`<c5 z_(KtJ!*sXK%fN~O$Zen;gexh7N}~?M{&|sI7f3b$D<;>okW*$P{XM&=&FVCwy61j? zB`EEJEo^%J)9Exl5SB00LGWw{(as*KnIG9rCXJS^JBgx0Rx8_mQ(P19|7f}jhN!}A zJ9J410!ky@Dk)upAVW(th;(;%gGhIG!_eI&EzQs&4blvayu-ck{)2Po`)2R8SL`D? z1^5W}7CEFC3>~zZp`NI+#1S=WO6LuDu^1_hckKapo%^@hHH$rd@gPpZ11TLG$D%(T zPHa5S6K)8(ZM@4wQ5nkKC{N0_+I4g^=bhk<#nlyCgD2sp1{YqkJ@SC^X`|6y|G<)A z#5OH{+)CE00KoHNTjQ7m{tKGa;*-yt{%Q763BLtQxj9u)WYbXKf^>a9i&)p^Fk0CW ztdQ1QH&o0dS*PScZn{w_b=+S<x`U_;(+1B}tpF=+{mvw8$ALlev}MV3^lK6@K)y$8 z7M*nkdjN<UtecIvH$cgY>K8b@rgOo`+`aM7pfiqqz|Ji9E?=I-WcW`oRf|h|5$_l$ zo*$JUnCI8Wp8fr?t>9)$3o%a;cYaugb2=+dS{b|l%!;8uTQ4wxTOX|9ig0=&Ex&gZ zx-7hyb0f#I{c26Bldy#9V%_>CGKqdY<u++UI=r$cZ0dHM@HGlOBHAmoU{`jbS>fh$ zM|i5-5m%@2>C&i}EP)^=1#~Vqb3O!*;guctVP*=nO>Nor8okZtfr@PT43#e70MY5g zGYAJtj|jk1JnT`Or4k(>ezhPn4<MBgC&0<}P|(&ZB(5RSC+u-bWikHK?4DO=twQqs zh-NzT706+hkWN}Q)Ka0POdwa>qOUk-w?$c8h%Q%=MXV;!d!LF<`Sk8zyY2X3#VJQH z1g%%si>hxCEsh3xd4d-Qc6sc-6bucr`Tc;NnR$=#iqt5!W|}|uGmZj#1JZ<QQpt;z z^~QDvghesmdPgQuU{xkE3^!w6<+}XuX!sSoVjTAcyk`-`Jb=a_<Ek{E|8-9yt=c#2 z-P*&249q6}T%LZKxq5aL0(Jz@c-ax$iwS|KtW0()-gZi8pS@PI4ymsxI8&kElhy)v z=d#8uokG>nU_r||Sc12!bMcm_DaS|9ak(%=wswc;pkO<ANyE8YHxY!5kju-a{Mf$# zAZo*()n7@E2+IG2x%$o)1h9D_lYgl^o$fv+L)Qrq!T9fS8fVe%mfZ&<6T4@ngRuDZ z_v08bgwB82huWcZNhwbHO?S1^==6fsSa3&AC#NeGe?1=6E;z9(YLl+Va$oSRQ|_ix zKD-m=k`iA6G_=}Nwy4pH!C7R|!#4~+&*5jJ>yD}1(mUyR)&{}6TLrXa=0(<mAB=7r z@jJ$iYW~JJlNB+n6r``zQ1prKWeHu>tGe(f{SJ-yLBpqwC)w`X^2W&K$OvgXYC`!p z`@69VxE}d|i#|F``niG*)l4f4Xj4LKsTJ%*Y6si)3l#~v`#i16DLO99Nr3MS&JI(z zE*<&R4$L&Xm-!Bw56lD4R_V>s#x6y5O3&LKk>34;a5;<9u5HwsFdegx6qZ9#sY`Me zeyKws$`uk6!5C#WU0?m&ek(1kYL&yFONsr*pc6IbYUb)ghDjtLgHwtCteIyfBn(#P zIsv#J_Dro$VfP<C0v?D)69`UQ;qCfeON8^Wn88>q=${xnYsv<`YA0xiXTm-AUf=ca z`VG2RmnnIkgPN*GuN|9wITM|sr0k_(&Hi}%oz6i3tj%o2TE>9-vhFjyb?T^}=(<!p zq*Oa9?*{o0IA7clDeEA;MJM8)+rbiAu)c#)oiVG2BJuXi3asts+Ar{gu#l^jwe{h< z=WxWas`FBV<x>(eA1sSw{Bg-k$e__A<ENgfUJL2*svVYL#*2ret;UU+VU$8z(y=Hc zIzyYJR_ky3wBE8?FQ+;_1S>&Edy!zsiGxmBnC&J6JtU}b8R&Eiove+0YmdIqxIAF< zoXdGX<gsIyeS`>~oLpY-Z6_fvRv2r0Q5KP!^9px$et*kka_el>0LIF(-+r2MK)*S~ zyRYJ3Xmqd$-dwtU!|5?Ui8&UP6+qS7$acvIxUv>}wQ3O-RKr<<@FpCMY!>bAK;M+6 zT`hn+!^FU?<8&DCkt_KN{6o_e_m(Uk?qxtOLqb4+z$)PQ^}=&DM2in=*_qo;N!ahy zvr-dwD0MtzI9a`D802)PTy*I~_WcM-zJFL?@UAKH*a~rKv^&wTzKL6^Me5K>R502Y zTe3#R1L>vT&;ugAc!6YvQOY0M+sG)Zh*Yv<zw&sqi9m_&qlcD9H0mCyBYaS|K<!Jo z7Qshzm3xmvOp7JI-x0V!m9kPZPo1o+nnkyV9%lap4T)FWWNslhx%%p43y-#l3f*Gg z>@MUfHoSEJ)jCtm;!db%!Sd}GzguM1s~yAgXwKw!@C3po>q;_ylCg(v9h%7!%SMzc z?14b_#s=@`lzVMU@Z6>HgGp*W`t|}o9%DbBU$?46&&TTd?E&)o_&~j7*50eYEl2Qa z2rJ=MM9(aK97qi;@h7%L{%x;B1#$SCE%T1^<a?CQFg}d|A%rytMd4W#n-ymQU*wyf zzBpTFC)7)1BMA)(!ME33Mr0HTQK`$8V+%SIFMmV1#0==7i+@fWn!Zd#%$s;Slt8;y z5F49D6tKAPhWS<EGi|N`P*=U|iUN}m0hB4rYTr^%Xtf-hqd`Ed;|%wZ)Z%cK+JJ7J zy~OS>hl@{#Du|*bkRYptb?lQC$9qnBW}-@qYO=>vyQu*1KC{Kg{$I>ZLqykXVsk@X zx=S{}dJESa`lQqs;uRX58YxfhL+7KEW3WW|rygjQZql1=pk1<<sIdz-YjBVYD)Ebm zE!pi}rEPe59Qy&?^hhz1@sxqvDP>A|U93;$j9kw4NBOsj<%nVb7uM3zlGGn~S9oEJ zx&e+x$dT+l(k<?1g<3N+0J(*>@%xCk#&FfyFE!fjg=wqk<52_F3|`99*<@wcbZuo_ zBHv??mBDJ^X5Sa-P2@m<4{sg5n6OM*=?|mBDdHw9;;WX#R&P``-9}!073D$<^4VgI zz$$W~6OFO_=}@qgWk>dj8p86O`jVYtg`q$dCxMBc<PIPMl}~GzZ2Z^S?lLB_l)Uj7 zXTHEo4tk^`iN+uMH>!EZI$g$dG`zE2jylTTYwNn(RYN=n!lt%pBS-km_?k8&Yz-fT z=TnwY4<x%&GQe?>DOEEHB=RHqMh<bL>VfD3cIN>n7i}4t{3Yo10l)UYN!;l((P&WO z9$>)cTHbKhe*u_aY-*pKOspC4_ILnJA`GG&<UOVw1Bz;%p5MuDih$rl{F?KQ^?%|* zN&CMD=xjd7(_*N2Vxg;IUi}`J6&v7YC!MM8jXdEV#maq@&OKN1aN7t<$uf){c`_U? zQO~N6$5$JS4F&jlsr+~qHP{bVblrRp1X2AcWdm+ai8aIgKqQgYNBWy1i!}nRah>uc z=IMl>r|Xa)f~VVz*5e;5D65YKE`xa^1RO->{Vo|g&9+jxEAJ!m{?qik+poI;SOZw{ z!bB&&nb3KNZtzzirwk?V-7)n{lJVvFf6xap3fM~!5G3ri_gL1EY1iiSrnp<|u*+<} z6uQ~>C(Ta9xPj#zZR(5xmPdeidEW)N!xx<W_&vx{p%!YY_4#9BG&;;)uc>V7@afOh z_WeDJ49FW168tdKEn0TYH!Yy-kIKI8vgEuWiaF>#<LY}mbcF1K(ZM*N6=2jO>fEcw zbLW{&AQopNXP=zlB{qxk7ie62@pRmRmW^cw#;0YSRZj$hc2Q5+whx@rR}_UI7z4pT z+2@ENWY9~lWEXLCcDi#_Y55`PvNm{hx_+bodJLNy9Amy7pZqa*qbG<OyQ47RXCdrT z6UwMJ74l8g;36$aYTf>0MNhuIs3ciZ?6k3<N~>h`hP_d7hS=idGRT9cl|}b@d3f~f z*8D8TpkRm?pY#6iKSBTjv5%mu*Ap~E`XZnlYeq!i%twn|QAk<_q8D&gbpC@lGH)GO zTf#kyrMWsE-L;q_1=(4r7{fLF@H}-GmjO!~&oao|7)Obxd!G=4i7tN7?Jg4U*0MBU zlOH=YWFkZEH$o2Cy_R`=9QP$y9QgAuIk)-IT>xpxWGIpFh4{uz7TJP_>w=;jt7*(# z-!za4!v)e)oy*bS?Umu)JeRJ3%@BQBUUYZtjJQ8%+~iyoeETH6Sua906_`i|rn&f1 z40qm&hvukTiPDUv;Ux$&>M{EWUAR>p>M}}XnhVS?LsuO}P!8H{T`zg)be#P7&l~|J zMM9cgu^r}*BER9a7+a$3OOIo=`&Y(R|0tbd1fB6*h#}kIsPDQYul8ylmm4AKjqWWU zPJitP!bXi5scy7l=~o%qn6bhSKg8SA`s#x-?E+gkjq8=bT$f<q#xx)$*``hHpe_q! z@-9?ngPzVGdL|Ws_gtGYuHVn`x*o|J+09HYWf$cC%G9Qj1m14H>dkBH4cNTyHT~^C z^ZL^|sEr;xBva(2;y_Lk=(s#t|6XpHD}qDi8<;$SW6{pvP;0shZ!b+z`0Ip>kn2;D zyxzu8a;zJR74WJ;wyr;;o0lx*lCU^{G+Gn|n>=mEuRc&M)(oBN-@ns98H^xd{Ot!4 zC3JS`WNR-pkVNvE3SJ#uAMQVz^ola4!RAb<hmS~lb0y$D*mcKzu;K`^G-=#F7b7h| z*03twt>qKXZzUU>%piYDB(4w^Pcx_sGos14z?M>AMhkIndr7hS<ZLvi;~%J8D=4C? zc@w@%9QimI(;mVb@t*)@88M3kWk$s-Zygs>YGohOlSk7$GSNEZ$c^?EDQ;(+78$?E zHnUmR%s8F5g%C^c>oGgkY>oT9E^E2{z}KcyVtHpVmFAC=sZYT4NU`jp_nEV@HR6|? z)7bzq3l=3f(jfwE5XC%nv}okZsSCk)S7T8amTG}Qs<+DYd0ZH<h*sAA=sL&tiSzSN zY84~(^d+U}n)9~-%iTGo%NOF}A`De~P;Jdas5@0UXd^$6VC1aw{mYh3^c;#)Flh!A z#Fe4T%l1Uyh_}_mIIEQP0k%sN>Gd$UdOzo-(XBQ479Qp!sF!j-Z)wFOd2k)EjDvgB zj@v#phfz##9t$MeB2lX<{5L}0Z&hTFS~7siE$icekNq%f^ZLTZs%3;<aC^FV3kcR- zL*}yF*8hL9ipH9W7P$!D{&W*EbkeAk%~LAJ+v7EoZ<g9)%J&1t{skp5_te{&d@{$? z2OVp|N`n)Nsik@r8pn=1*i}kMWa|W5cBrrSes`2G;ZB3l{c=4&aC(2M>#eXj!+<fj zA(CNDa0m6?m)(ub80`%|p^$G)U%Zy|n>$(rzv|x90!L`gl;U9;celAa;y{@O#8Hz| z*Km)U2qS;4p?S1QvwivbU57+IjB<uAP5)Ia;e@1Ey{oS%r#jaL<8*e(cTDTM7p-ll z!>5J17@z}^X79HoClr3Tf7{V;BA0XXPj#|0ImYV&&WfR{g4l|<xRX1Pa_WZDhy65_ z=)-aH5KnrfmI+@330$w2`u&5288tW0iwAdd3pge$KT%;b`9ThTmvP<F0_?HQXdn!# z4<f?Q7bm8Yl;x|owPOv+&xp4T4PO1sb%`zZjG^B&W3RR!S^?bv3E(vnN``x~>gGmy z*G8cdOAr5UZikmC<$x^bMua`kfM5Xlcm%-5qmTfb?6g_wavwg5Y)#@U32%Lc5wIt? z>fPrLcJ?a8isvBC+w*xCC*}#I2)c`zPB!GfSx`ywo%hcuJEnShy|d`wC=zio2kO7k z1qSOfYIl@9Wc`f7@i<B!o>rMI>nHW#j8E=7!ifG5dy}E*yCw@u^G5O|xz<M`KHoxG zdKYTR#pXaRV9a<=;y!%}A}B}k+P7|U*-~?bK?Rm7y-}jt6gg&#n6W55a%}&qB;o(( z*hC=Zqdr@J98CBitNlv`2zjod<Np1Kj#mD81xYt#8Z2&TKatvRReG6k1!bb=)G7YM zEgGv_LMPrJack?aq&2_BiHiHTS^MxmVipZxaH4P>XpY=QqwGFO`2w7uw;tSt!u?MM zo?D2&abPUDm+8+O;RegJD?2q_336|F)`>;at)>?Wpz3t(CZ5LK7aX55QkS(Y_L8E5 z*~vEW#1-ZyHiJxzeRiP&5|C-k`tM$)AD&_;Uq$-3b3(w{ENv0?Ks}YFALe8@-Qd(@ zK(e9m7HV@D7vr07_$n!5@yb|Y&Kf(#;oiyff{Hr_s}S8fE~;X^OW}onKuf95rh3rK zwU74GzS}VwPTgY)Ab33&NHR8gZ|+He>jj|T8s!-7qp=?Sc#G)c&de9Kv2;3-j4snf zi<e?`9bKe!$$v<!TKwg+FMoYfUE_*jl7SI5jG5GIo)kXvLb$MtHkUw5;w2<oUEI{j zI?5#OviW<NO%1`BR5-~x+3Yhv;QQtqlbiivPc<<>O-4CMXh<3U(_5rg`1?<jXDQaI z-~+$wNoFezmy;#Wi}z3p)h;xtX;gY_&`l-!?ZxL-?2a@^y0}7ntTAzk2eIG9d7ALI zei-*LA`ZV%4xYoIb7f{2DV4+k&I4{*uNPp!um`67M&m`&^>Y2GS4@n4c8^1mdbvq< za$0TIW=qx{;UFiZa^m8W9gd#KMQ2-a3A~-7qyn0(g;xwyNmGSQKjRRk1Hs3Kyzl9| z*cD4symHja$5pX9d8_&F*LeT%!6N)!Zbm(w_JtT^cN1#YE=tNPOB&~9z>A2hUA_Hr z`HSz~WR4(%UzPhYg~+TE<i4A%C0xL1%zmHT7C_!|AjQiaQWS15HXw*|4gYzU`f(T0 zsiWl~b88~m6%Q~}a>#olbqHO2D4*N6c8<Ks9c`y@B>8};j`MkAKxKZ^dMeS*`&E%f zGv8i01}c94ieTSB6WQu8VGCNPoB!l*@FG7B(J-QBcF`BpCUXh|@%;3e0*O7d7$ThJ z$zaO^&lQGuZ(Sn+2V~@5sxLdl!xv8m4O&fGbEA0^^l)Mz*V(ATVZ{b3<LyCe#qC)= zj&Uxwwsp9&BcbQEN1!&a@+n9;3k)=lnOGDYv!QmqIiqmf>?{S*h!X^xw@xVhKmZVx zw#82TsKTpp1)$W}C_J|(;9z({fLZdab3=fW1MS~vNdhCX?9b%cnaph7{%~JI!b8p{ zhs|j;xIf}8^sm4q2E7sq7hyTKcwoLi8n3#oL2?-kIb(eT1x=h+o<poIVFeV47aeAT zAtaBj%l(G7by*;YpH3PW<4TAqGBh%7%SwhH{s29gV`S*+8HDs}?e`bl$%f8oL)C5k zua7<=18#aMx!~nR^}tt@;%R$yDW0}x{`mwS(kWq^CXlEu^5rysCR=zNbe16}?cMAH zAia)B<YUdKcOWW^fA`sWmF`<SJ<p`HKg6-u+hkLgTEfiteR#d@YvkWIIsC|rQY*?N zNxxJn7#!D~W2J6^&r01lUDZj%UmpzVQ1x2uMdBqT4hgX-_b9O)53yfIz7#BTT(U?7 z62sMhnmgNk{(_U(QaqY`{^DpBCqT5ylUBvXPW%pMJ@ieiUyss4IX5wCPfvE?(4j4{ zio1D()VD7r<uVtC!6aP54YOiQ{-l_KrFKTP<7I^ZopD=5tq$U;mi_XQ6t&)6iiO=( z`e1{mf^p;)S!X?E@V7ltBNdz9=f7#oj6&XD!KA>22(wq_JW^Mz1^0cW{`@X&-SlXK z+Y#-<8QCjh+#H4~zYI`A!gD6`I%*|SrxGIA+X@kSk=Lw0L6E(1`~A<?S7=}g1zBle z6a8?^de+FXfNnQ@k6w#C9o7X$gVfP8v@M{eZ8jfP(XU}%{5A&YZ)?F^o$P-D2G4dW zAyjZhnb|V&-nBfqUmTo!=|GO4%qd{Pmg@z5)I;R_MYg^aabXX;e1nWABbuwD1@#mk zj47J28_#OxSqUd@fE;GL0Y(%F9y)k=A`w&QD#ERn_~r5*I)cj!U0h&HxwcMujxI^u z<BS;ehcz6|zWD_|uma`~FH-|5?tO$khL7ljYSHg3zvmf%F&)`NHPJ3d6GW#j5-h|~ zB!;`UO66B-ggznHzW14@pN&QSaW*LEnQj5N9wE;<;29j9xcKR|@5#(;r>V>W+ySAL zw)cf{@0f-C5udXq*KEA|sd+ey7w<!P<T{63!C8P5X2SJ7Orj^3^~rLt{#q}0H?M4Z zMwrS#?@8Ae$?UtXO9APU#VYVpD^~t2vlSlu$#UqGgy?v-;1lbcjKftd-2;IxVA!n& z+xfM8HMNQtxW2S>QrdKfJG<IG2yeO1BJpZwQ{4&mxdhIC5{NmMC1J~on`0VH--~g% z;pVy%c4LvtJrVO>L>1gG+Zm5p76sf$1nbSBD+Jq!PCJaM?Qziw#}X*2k%oMVJ<@nb zBJ<^}z6ysX8+A&$BGTe^P2b0yW*%)fwUCXSOO9Kjg!$+(`9!=E$-oVp(P6q3VZxzT zHcVQ>?7=JrmU#bkSiVn9kWSI@MiVjF&&VMXJc|`;kbCRbq82;QctvFZRJb#A^+#MS zoV<jpp9D<)#XAl7g(pc!YKedOnQS~uct}O%4FjF+J8WMnb{&7|S++1?)<V}E_m#0A zZYBlJ|J^F@jla{UGk-@Et><po3Gqp+7?d-Dq12PnY9yB>RiY(@(+vuN9np0VO&t<& zN=Fr5^jqs6-Y_AnaGCiqbEL5AUF`j|hp`~k@dWD2iG4eZPd`ao%pGjF`Sl%10fMs4 zW?ZPMQ-DwIlYih3ZS8bsj)z$_;CEvdtUIX^Y!N)04Ntg@`mIL94OPc&<Q>*`9Q;HP zW>G6;O5>ecZ~IL(bKUFQmgQ9#@@QO91=h?^ABy>lP(TD1Vdy{uvdT>5a~4Fp48ycw znGmh$rjE&D&KzuWF@av`f&=tOGeM$Qnv?!-N)yJ!rh`%#m#Ow=7LLP_m&JBt@x-^8 z?i#%caq2Vq@iqHA9OT&TOliuoVDbv?OJtrVvu`48PNa5$Kv=VOwtqlRL-5}~l0Oh4 zmr9#~L)E2i0z$4<6?7^|j6cf=C%BF0>wlYyFU9+&Qu)&HyG783(-$3kjiM+DeW0YW z{y(Gz90w`@tX)g@#*kgbuw~VA*!n}a<DJW>EUCuO|K}A{qH|Y9+EScc-F1OkwL@la zrohkFRY_&8fj6AykZ~;4L#@<UJ}bMUe9q~Mgt{3FrD;a)80t9m{)3%WZ|Brx-0$us zmyS2*`{k57vW*{gnI86l#VuK$PdDu<+VgE}pTcLx-{@2}K+LdkvJe!(KRm0<)ffWU zxtKQ46;d1DSMPt5ErJ#r{1{k7H_6?7*7F&AP|N`h{~5f<ClGIp#Ep0JnndRjsx5H8 z^pBwbQttp(+W4XLAu_P}7pCyAqI1(SqrPNdZhLhXB}MOS_ZS*~St7<BMC0kG(4vM6 z+@vInfqfnO_Og(L+R|RZxmkL%@ZY1Y#9C7gRN3yZf3sjn<gsAIrM)Q#+)DfH#NCNC z{o}AK)1wHo&b-v6(O3AyAt$~+`B}Cn3>*sRHUyma?k@q506bX_Z;@VL?yl*lB1=+O ziPO92oa?n+7jMzi%xTv9)+>lyp*wD&g!y7n-g)my>f!l*o%uUKv_)&(lsheWHKG?* z7Ur(MW7<q#yHuaVp0!F#zSt1Ei@?L^DfUF#?|T@2zK6BZ-R;G8Glz|SEjv>k?{JE4 z<*{`uWEPz4=o1A(N39ew5Isdnt0%<pWojcR-Y$hq$^8l9-M5cR{Q)%m9cm!Fw5A}4 zr6Aw=D!Lgr<0CBiGusrC8lw(clB$V!L%BfwtQsf`55iS6n<AsG(%9LckX0YiHN*ez z*F7baL$(X_sjMjNPk#J)?9@cslo8h@SEylH>r06g;rX>%6}R2C{gwzI?4IRny7rjB zX1Pd*W|OBg0za^vhaWV+dOcj$R-D_Jd&uMl((_~H)1frS@Jo|~P`iuM<uZ~lS5BOb z|MLQ%4C|{NdC~#~WLzb7#iy%fmnDmxWksGCO@_YTo{ba#svAg!VPfh@--ZWvO!)V> zZWk<6v`7ZLq7cDLn%7B34y-fPC1nBVSf8U!D{@rs)8a3eBkG^0O%nH-V2TJ}A%}ks zRQS_fn_`L{>x}H$VvCw?i)mcT>hq%lk%TsEoXfWt0vToE$TlSNb{P3$A2WGgt+q#E zA7nN}@@{>yAaDkVyk{-73vhz*7WrTn7{}{C?}hT_vdl<^Dvy{+H*Q)~v4#9y=|uOC z`xRSre?{~Q<yCIf+cVGGUmN4wI$jUH{DAkxZ-KwC>s|<%VnF|}o~7FgBAfOnwPs)T zeE!2*@+C*tg70k}$So?Gbbpr*Mja^UJ#4JPQyqu$ymHf5;pW;ZYimLzl8iqBjQ_lJ z^zW*gggC-B_!QKVWJCEi?aERMujX6-lU8^xUP+bDc=qu_IggOf4u8a~;Q<ev2~p;* zx|*YG(e1QkiSd^u^a2G<9({dy&li;9eBK40+^#M*fpz1Vo){8Svq;Vqxs)ufB8Q$@ zSb(gj6RODwiLr8E%Tg-|*5n~hMYUJ4qZY4vbsvXIY(b!)#q&7rne-7<Hsvf&{c1J$ z`>?m0?oRg+r(Ky6Rm5@pzK~{&j1dYW^Qcs+CJURM7nG`R_`WGg%nr%Ko`PQf_a{Dk zzPl#!4=RTfuN#BaWE>@j@QfKVFpga1)~Ry~K3eV?g8B6rcSa#Mt&#KXZOar1*`cSX zd>PR{2aqOD_gQST-i5`(?X9h|)v#0985wNdX++TxR?NPJITTpV=p=~1erTY#AI!0^ z4>IE%f_MGgzkSKh70C#Bu|TC{HmA3kyQ8B9Tx<Pi4Lvuz68%kgLM{Rp6aE?SXN!>i zuT<lKCf;btv91&A0K|wJfzM_EZSGe9BXMz-;2q%&j_~i<fNbJ))Un5ZO8#_2k|-)s zY<v|&5lBXV6|ErA?}BwCV6++P9Sm8bH}eKw9w`~;KPJTLo#RkB{O_@6%kMMz(>TcR zCeoCGteK4J7t04~OqeOeZRUoRWedc-_8$oIb8JSvF7sQdKcTl%r->{?4?{(lMVvhX z4`;R42XBNb2)2<$le_k*jtrG^CoJ$Plrx-7T@93@G1JzX&u6YQn?$`l0Hj1A*)00F z1qc!%<75HBmgYO2vf}aRLdk>S7zCnRN+%vS3?~okugMIj<eHtOH0#^`oO+3-tzj>= zPNA}r+2LkH8l*xD#_%@MH~6^_{e3VqdUswTX7g6yw_w%iIHehdBAg{J8|5K`Soq3$ zSFj_Sl-p{dM#62%fhk`|I}T^f&vY5S5RX?u)dz4J$GwRw!el^ubVrP1zW$_l`eLHu zH`%fn&?gyq!zpckswwaXOhY3DI$H*SPi=dRof|4Q-lYjk-P7`D5^y?vX2cFn7hz7I z;Z`o>;8Mh&#Q;`5TjG%@a(PE^>PQEIpsG33gHGb&0u5eSrO93OVw~kw;YNiN(tH!J zgo5re?#4IaXk$%t6XD|MK@*j%*j{X*nbPVcWfQa>)KhQa!4c+@2|q%v$P))-<A6bp z<>%q-r1r*t1%v1|>4UMi>1Mx)_z`?L&^jA-j*M|_<Z~BMGSkVw5Et(P%D+>t19361 zAjOsSn<uz}$D)>^xuFwFMT=ubO+b2^rLBT9h0`qoFnX@wTs!;He27BjWEVe&%4owd z)Rmk69QGN#AMctTE%+^<eMsRE8hq@_$en7<3gI%a|2?H4hfx&TdpET*MB<K|NNQ9} zAU<C3f!9jOf!(6+vsbPJtjvPi7E>qD95a7WDq1|@-l&*N^u75#FgBi4+xn#fE+^b_ z-R$2Th+l0)RQ3|8>&<u4>q9QT+Rzknke-s{96;g)Qot&edKtd&{OsJE5`#i*FMrP1 zbtQ~ctZbTQ@K{e<=hUHuuWVc;A1}2P9-||8z4<Dk@bP;y`-(=oO~1rmjppa@_^Iqw zSQ}87fy}PCp~I%4`kK&l-Jrld5@3xYiaGq6)C3`KB?tJ{*HX0sM|drT)>zi~FVbFp z)GhyX&^=QiZ{qktkvkoTIUUJ@OaC9Q0gll-*%6e|N;-#kV}3+^6{h)o&5C)zI=o8H zNsGv?CY~t;*3m!qTzz3R!7jBSNiSy3En6Fs)EZwAc|(~q4g=qhAtfyfg-m0h+x++v zK4ZV)ge4b5PLp{(v9beb3XBxp?wq$Qrr2Hvz)l{L_Oitu*XzABARQ3F4o*aVd8%8P zxGTc1y{%KZDy35i4Z6=gFOHLZ=M;ER!m{azk4Y~hKwL}!SdZQVVU?5XljGGZ7I)&} zaUiwN!@S-~ZA4gGoaLYP06(mxMo<+MrB$Yrf>xe6P1&}2Lum|U&6Vh_kZpYY#t&V~ z_d??n!#ip#6E}GF7t1hl{wnJfd%sn@Azja1B=h7K7v*rXs$fabvTPYc0aKGxv+uHw zMB2*E)49(L1w!&<vi}(FBfc{KRG^}lu*AbRGwWh|sO5B<S5fkmcTy1H)b37c-`+y> zC6@mdool_snKpr|V!VnSn)S|Qw^19|i}3lkaTEeT@vA@HeYRfT1l~i$s#Vm8%fSd+ zy~ya`j<hJ_k7<rNpOSzZ13mq_)UrgzkCFw18x6y1_x^Mxj7Mn;AQKJqD)UALWPnLx z8IfFVdF1ML;z<aGs-7Ch#p5fB$CD@%QKJHiKJHO#XY*n)*TDzdDRxm><7@O+2XuVx z_Akw?yLg!fWKIq#9#_UQZ?%3$bBiG_=2J95=yt9HXlw#$JWjAFg$=M*e$gkC?<Y2> z$xoxw)Q<v=Xpgr5)})6_e;19%ni*ioQW-bChN&`EtHi!H^GT<YzF6lsCHZI4c%8Xp zc9YL;<&n}Rg>D#}>(AcUXIL8E%7p>u&$W5NC1(uUq{*&_*rFqsuR5y9d`*Jtl)y-& zq3zpKADM7K-wHIXc?=~MbeFS^Bg<}BUg2lz@&QiqQ_Nh@#?R}YtJN%>j~UwYRV;|1 z&zOGz_YA5Yfv(We!X#Mk#}X_IUSNCf>Z5-TgBDN@@IBqmHC<y{MEgZc<v@{Sj)nR- zj6R{QZulEv%l_GI=Ux>stjpCDTo@s{s5)a7#O6D1^arBcxqMdl5h8Jk9UTGFml>v) z%y&b<O~HpPED`RkhB$aMIY}f5T7Vu%#5FUEH6-Q23DFY9mJZ+5LQ}4baroc`gCGAp zT~qMh-2u=ZA;S2BwPSnB?s4MbY-Cqu$mWR-rjtOr{79pdUuyEgrYOMH{8v0+#uH{C z&m-XE9_y7sUv_ub0HJrbf=9wkO+G8`&5T;-P1-j*-O3TMrdP&c+n4&{5fSGG5}s(< zbyg3(osg&2mi~fm{I%CYr6pokN{DBT{LE}GV%WUbDS;faR2z^gf2HNS@bJeA%Ef%z z$>B{o9I-z6u}3CiCwSF$X`;UKqTfNmd6)|WeKG&vEI_`~5R{R?%I5N|V-I=-jFE<| z!F~SudAA^bJ3y+xb)SsEQdQvO>WDN(iUhs(Kjqa$us}HdyxfK$57R?g&>>Dxfc-<? z2)3NVYV0i>vkENzV0KM%V^Wufj2{uyb)7CXy+8N6SG+G$CrTOE;5Vz>-cV{|YZ9s? z!NJkA&KxpwQ{<ql7FyQc5-G2D3vxBv=kj#<SG1lB4l-j%Sc@Tl=+{Q8e9Rcn^7@X4 zUyilPV#S%zAEJ=J2QY&gu`QA+2+}*Ta)dMFrJ6O34u1SG&my}TyP}CVNpv$2S@kE3 z%Z&K`-QEF|3ok66fk(O0AOBK$y7rd{iNt3bphIGEd-d-~u|Jk;qWLrz;OO3>YpHbp zE~R>~L`42Oc+K3b6U|cK&X!1i4626as28I6+AofMw%)7BbNFhxVp?}l+`|1I=Z87` z?T?qy4lSqy=e?bt1E=uL>)TpA%K1Q4-N{p&tdvUj_Fc&shxWzuA_|BKLqM(28`pos z)h{{byCa=0sd&&adRI}*0gpU!47;L&H;pUz7?J>;qJ8L;P97CT_koPmN|N7_7^y5# zK-;<In20QA(e{T6IvJwXF>4hb`ilwTLP#&Cjm4b*%HXfr3W;5{pgGJ4Q!h+3sZc;D z|FSLRwOE4?6B;qWGInqq|9Nb)YH}Gbbj10kSKh9i)7#`y)~+H2PYj~N?wF1W7ov-$ zUp2j*b_1u_ooUf`cN^pcts1<|kap55=O|y<;dE7nx=ck(?`#JW+2@$pw`Wpjdwt^d zRhYDyIX`#`Sr%BSoQM1Ky%X-6zlp>UclM~?;@_&sY;{Ow2kJ8jH1-@OFi17l-)k_6 z8_Mf1CZpr=X-}HLTP&QcL7><BYTTD~wnW2YzuY7?`Nb^*Ay#t=+seANe3rBVd-usL zAF7E663}KZ*%8)fr)WJ7Zq}HJ1~Bj@l7?_2j6;MS?<e4$kHD^u%gUmDjOfGJXUf$J zR<;>3;c;-Iez|(_)kj1uIJT%gL~l$<1>t$(B6z+xQ4LWJgv=r=i>!0<)h2ADN6UEQ z?)%E%L;YHALO~`x>OX}n@{(^uXFCg#nf)0zsad+c0_)AkNb2my+Bn~SU84L76}>06 ztha~Xx@o!L?fTLH7pc_78(3PoZ(i#rt0FT190KW7hDFQRcHxUvoe};wz_J3)t(N7N z+_qMzF44b%BsB+FhyvM@_V$V+0wS;|=`pW4N7{z8<w_z;<X*C}qa0vMeEvFX7B}iv z5`m%WjR>G3-#YKwuAj#>DzX}R%J&lgJC&=~T+8$~hEQ81I(gak_{TSYE;e6Q5p&LI zC#4GiZB=04%5_hmchB$Nu4YOKKFf#U3p8D9HuL0~WY3<Oxi3QMJ*hKzst?dtK~FA# zDVQTYWcMNaILETlzF1C0)>PI-(?7k|CizYE%e#PkoK}bWZS%3OYb8LAw*PBCDz!Wo z;*n#6o4?pvJox5#`O9eufe(!57UlKm<&Km?FJ-&aUaHT<_QhIrEL{P(`_Z6r1X#66 zjKv)R;7Q&dwChzYgTD~Gwn&_#lh^4Dh4Od+v3s+=>Ou3|vDg(2d=s!{nm0?YCAOt` zBdn}*8wq!oy0%E{Rb(xC4=4F6v?k<!Hk4TK>ana9Hk?wMnU@Y7hViO)W~Jlv7Hx1E zQIBc;IUQWX7V)_>OCR}Kp`!=&RjQ$e&RO#8vXsHEbsZcmHwET;=ZFsrW`kARBYxI% zr+*<nbW7ylS3_JwaDsaXH6?UR(!-w|&qu0s)FEWPIdV3}tO5@qu<MAYMOa}b<pbcJ z`xE~e;!tJRe%Ia3#$n~Eg1fpm{UN}fAE^_{AbRs}^n}zaZ;ArQ4QyczSzo~sfO(|e zl(^XHLlLISjX%c8mdRU5YT6XU9?2fc-Qh6~N#DLP0!MG<U2<R_<`Gd$(fVSsw!=<2 z5rn8)^;1?z$r#zEP5$2f1!t*_)Xyl1&fp&<x`f8RT83CGrYbmQnX7NauJKrMk`BtS zppGnjmaGEhU%XMef~(pcm3BzDp$Bst`_04~of)@J-#Qw~9oKT89iyL}_clFRTprFf ztof+nPHz|g%T%{pDcf`}-A>$XN5{)UKR)kXve-c6*5uT~4aJ&?I@Hakz-|?V@BU#t z8qKFp`{i*@AfWy-Tjm7LrMu#ZBN7q&RrKbPw_MD@3nm%3r$+U6pi2jp=0(uxG9T{a zczxDLZym2HeKfa2+HUx+m35fp3a%LUWnujG_X?u$ByQYl{5#oNer(VW*=9~3I)WCo zG`A%4Bhbe0Lgyd$wWw>Ej~If^$E5GHbyZQ}w&62Rd!-KzKJ7FD$$!1|7(8KR2|?0D z!~C$a>+WKOgDD0$(F-m7yB9jy_#d7}S{xSQV$RAvm)b8UQDa+?olAqT(7tNCocwip z-*9G9f>%QZI$t7Nq@@Ck0?C~Sie-|!%@p}rI2)mlqNA&PZ0zF%rd6WfX__WIunt0< zPZ8fG;#zrWX-1qSaQh}>v@e%uIs_`Nep+)IN?V3u{m$R=S~NXwsnJ62TrBTuH1<LE z;k{)`E`6n;yf)pwsovrFZ{HB?mGL~AyOs0Z&W01VAI_p(Qv_Epze}<Fs6y6Z4L*O? zih4H*)=oG9(;ehc=)xGqbDB#)$0{_aaNiK{-B`FI>Lkyk0Bc3JOSzo@;38OL`R<l$ z%Sf0jxK@J-g~2{VP`bE@QP<m@QmH4#dUYo&rDY$d2<xItqmlnpQJ@Bti*z@6c<!eL z20$ao=YP`r2sc*u7Rdi3o3#BQNS?G;Bv*!%H{lZl21bF@o6Pjvmk+(SCtdx+;-NFr zwGxz_P@8cZPhihl+{(#eU%>rwxNW<;#S;7grz)!{r~p7tTb5U^pPj>`Ko)}og<X-G zq{eMD71^28s`62{_#&`{gGN@d&$P1F<2tW=Gj-8;Y7u<9IHnheg5Y%>rqRd_Wx>T@ zi;-7ryS!<AoX6h1E=N#uLUl4qfAu&2BwOIO_^gwH22USmHNJa+riiu+X;7i#qxKPa zS6}){R-k#NPD~1>nVaucYrOUrPT7+*E<*km{`_A6T(G!6RX%Qvy`F(ZCEj{Xt-HgC zZn{<_-mMBv;k;MC1E?~BN;5mEMU;cu)3G<6Jgrb#d914*7$z;B>yD>mJmcK(EsPwT zUqti7SW|HCQRSvt)Ks^`FjU__ajcciXl<Q;wDHF*&2hqF4D_w)#U7VaMwo8p!pR_9 z)P|n#T`7~UrUegHg4AYt!-9oqdEmc^j(ZEvS@G&)o_O#lG<Slhx6F>@5Z<slMag{m zu@i}u)#vA4TN8F%p?U5mHH97Wf-_Sy*#8kEqbU8o0Da>KpwEHay8bRAoQ`o$&ZPDb zJ+PH$+i1OV=r9+YHr&LcSnF`#c}0Fue4g7=;MdpuKo;gs?|jlJPlYfc!lGJeFC_r8 zmipXfSPr-N9p^CL2eqiw`t{En4nJx+<S`j$>8F9Ml(!K!K!7wK2uLCnl+Z8idpnJP zwNtN^*;6HnI#>r8AL*J<U=6eJsBMsPiUf9wJiQuKONu88NLgJ5UZU~jb;my!0%bjs zMT>)u!>_zs?r=Cju(duLt=GLhfC=+?A&lhn<zGi66y-Fj?7u9d@gb2K>qY3U?+A1D z0MiyuD-KckPL%02<X6b-ru7TF<jI}F^H=ZLbBSG}u`B8LY`#K4E!LU0@=)IM!%fvg zdw#7*t0YZXZHHx>$tsxpt+P1rU4e9v?^_&!36Exc_o53{la4>bQ!)H>UhHx=JJ%fY zo&-eZ!xWNx<Br!+Mj<{IksF7Uj}Hr#dS({nX_0fOcU$U3EGR(BOO!}Ll2iepY^tSi zI1+GumLSt0u9|vjc7M+(|NY%w(hl4HCN*~|CBC2-({`?0uOo(|nc=R$JeN^zm{?lx zQLU13Hj;h-Q*WzYR5TbaiOIm@ROaAz!>0}<lRAxko1cRuYS*k5;q*xM4GG<=K<QS0 zQHJeL71D|To1Ba~=DRmb@|Ym!xX<tK1(lx;YxUG|vd(^cQ;uLiiP(^IY)tmS5AG&; zIz`^AXihajyvW<o+{|iS{8CMK4ugQe-UmjxTsjAp*FoTP(9`;BKa^nGH>JG7;ciF- z6(UE96-kJd>M97R#LL#a!}v#cGg4o8gr-An5jvW+8SNVS<PNJdvQT2FEm88bF{zRN zo_xg+VoUFl&HINGJ}e;qHxLpRL97eYjUQ~h{#Hng+6vvmo?n(+?{@ypV<o=98&S?v zc3QDO+3h3rs4)D#8WH)j@O%kC8n}%*mGnE;@IT#N*SAo0J?v)4(K$CfK)_lC(0lQJ zvMZ(m{*5I4`bg*6T6-SporcAaNex11H}L&m_2%Dk$trEFa<`E*$=A_Ye(<$7%ko|q z-_l9nS+1lv;HH*LNcBqhGiFXZA_hvSL^;;whTDW|{93sr!3qJrJ{ay6Rp&uZ#Mfa; zI+*g3QQ1g+DUj3Y^N^X4Vy<66o%YY&VA$@PjW^eEDQk61BEt9Z8u=41UMJcN$r4CX z+E-WetAW#f_0D`gN4r2@;WfB<O(6vu#j;D5AcWrrSV8Q5126Lt2E<m3P)9%aWd}bk zs}R}twsJfIqCxQH2Y*oUZJK6CA=-ds=f9vpe37uR2eDo|ge#IFcW=S3d`-=Ycz(SN z?3X`>nh$u;nvlnO{BhNJJBXRf`MkZ}*7=CKP>w#Zqx{_`ry~7cAfTej)Ny?Pt6W_B zN&cO|5#*b)I3-8m&$)tvKEG7^HIM?fJmmCQ{zv2omr47oK)C`VT?S<|!&$2?7h}CZ z0NQ>Z{GtsM%a%U4`3qOuH81<>j=MkhUI|X^{4=v@fEWIo<6lI=G}(lW9|O68r#E?h z#5uRY>F#?Q?YX~f{PO~3mN<II43+Xa9!I$s#@OdgdbSyy0<D7@0<;mo4I}tgT@a`= zOJ;vx8s0A0ps-zghvA^%YO%7kx{A={HIrcN1#RQcWBR5Gtp3m|Csgo7_9<!wg?hG| z9DZXtvr|qdwtg=fZ{KuoIxyEiT{ZU<Y}q3+-hTO1d%dHSN<N#h9$_=|V83QQJ~~{k zi~pSfUtFB(MeGYiTEi|xGpV|9yL+l}S5Lu#5xMJhPUrCn2#G<<IN9<~Z~!SS>bux3 z9^=W5T6Eg4W=W+rSEZxFrOO>&ZWjaBiKM*85uqFwBc*rN8RaMKuGPz-#CAT{tJe@6 zqM4-}bp<xv&f}VONhdRyC-+kfj2M@^YTGJARH%N77!ht%Jll&`{L*ejnkEhZC?J#C z_uGWNFS!jF&4p;xdum9Vq<R^su+xNUK(|N`qpyQJ3i~xFA7b>1b|8<}FR(HqU%y#% zw!*e&?dY$6V(tZ8dctsyK7@37QN2>aESVD3hr&c<OdhAoK%2>C((ewH3kNx=fS{** zziildOu5t-Lqr&uqplao(RLM;I8nBAY-vN_aqjroGSV|qhSm6&K1Uq^bct7dzeKI5 zfN&cm>V<M3c2gI1&|iKJ+tI&hDr|PLtM@~f8mhIoytTK;8hkb8G|KcM9lpnT^r}RC zuotmvTW1;JcMlpH<v%7i+<z#_B4%GaeZ-X4V|f?GmUiDQ&kyi{;`+oDnCk0P%LFAX zL<k+VK<yfpf+@<({~W=7{!Y!*d*jYokvm#cNdgb5b0G{x>%!rORS2$KTX8xfnC4=$ zFWsH?90cxuJ^$he+<Nf>H=~wrXOUjF`|5coGh=wgR=oE^6E))5-$kv=5*<KPexd$1 za1$~_Zp2T&_!D@es{Pztq1DtvIO}&3d1ddd9KOqzNt{b6gM(Q{{DilIcva=7t}95B z&s>;Hi@BY9NmJF8Ph;&L$up`NTBXbAP|T}U%S47$J*R+&f4mAiG{z-1AwDCjT2Mu8 zfJbIT?#RDy)?r~Eqfn6BPa&&F^5^k_NGxqG$}idkLsn3ptPZ4)Cd!IZavRr7hA%o@ zs`&1|H$y7wB(gL4&DoI6BLoMe<{adf7ws@?us(gWuCLSGLNuI;`fL`e;3??OGafMY zNg@4!#V41CG1*>{I%N3QPBZ4K=^87!q1PlwtrT{FOk%39M!v~VE4PFME1@=C;fhJo zc|p;{Y@4d;Tn`(*$eYd2gvw)OBZ0`6$(L4qsl1cZl=f?1>~&!M)TVmnsGBI9@$f4B z?BliIa6^|}N3r+Ak|6us$m!sy1Muu7zCFI|*OY7-H*vZbD%V^R*$thXB7|Fn0NDV* zk_j66_wzqEChIY?D><daV9Of~sU?=Dif_NiND$&CIsKk3V|lWB+=D%~fBfqIu8Ilw zi(bo)IYFQx^q+%)F@#h1DE5yyG`w|>X`biZiv?B0+6by*a(31uyLWAt!%elUQISc+ zS&ATDL{TCTRhn$?Rmb~iJ@k(mhH0ORTG^5s*v&dz5vOG&DKXE*3*WfIKYnIH>3n|& z(MTfwL405<tw#j<hY6bTLZf`TkBWfg9Ua38=k|Qk+t_dJW*(m~K_ZBX5j@FRf;o7_ zQZsdV{ccUWqOTF_)o_Y@K-qj2aTopwgNMpm9yk1&jg}tx?_>|thb&Nt!(L-8^F{iq z$E5QpARO`XtAiFDTm$m$cJKZIAG~rbeV8Af5~f`RHG4B*U#E>1iFVKV=?_wgs)Gs$ zwx>4bwu=JgNwYa-!$nHbB7Cxx_8}nOI@w-R81vqkWB2!?cpvXwD#`_OBrh|i`}l}+ zd(o(oMS47umvQdO-&d6OzM^0X^SEP|;~Kajaf#_7JQ#tZn=MWreLU{_oW3N=*A0nL zhr%-6EN#)gLQIHAbzbw!$~n@BDag-uqnO~{MZ&*nF?@+?JXdVBgZMO>4(!Dxv;D#L zd)fraVd8@Sh>WryWO%mC+{pTlxGm$iy{l(T51nwNT?Ebc?C5mbkuSE8SM;3jaldE% zokVcAig?l3Hl$QtFN2MP^_xW-Lq@<*?UhhVxXyTv<$k)9g07(BONafR0;A!$_XfVS zmj?vTrD-uoeW~v4AUPs@S6|Qpd51&^SB+)M3<GUTK|4T9Bd&sdfKzwuLy>&|g~M)F zdI(`0`Na+Iv6nA*G>5=px7XL9tO|ax^`dK>>%>TkO?BftJ>)X7EQL#KQ5X8^6eLhG z8{zH<{O<4{cD+;)_QXkY8#SLs`T{oSEYhx770q)0jgT%llfK66z%jQ;$BByr<(sVW z-2c1)4p4Hv8VnvXcX*id-Yidr#yO@Re>(w@MgJaRNWnKuADkDKw3=@Cwtp^FUqsRu zf612290(V*-DhKFFLt|kE`;9E^!sWJ;$y%Wk0*X5t@v(?G(ly$#^b~9&3E-3p70zC zUuL6;Z2}+5y|!9fb6lht$lwu010`3m3ZkM<2uuTwrR_(XaV;_*R;KVk?;N*NhTWDu z##ySVV}}MyaE>~qMF_-d`UlM`L^$pZ9w2%Ii&hXNDYbqHb}tukZoUBRt?~t{wUK@5 z_*#JUhzd5M*-%k-rd9A2-&{XnS!?8*kQLRogJW&;G|V{pxlR=hWl7vl<?b|ZAMN}T z8!VW<k=>MRz9|msjw_tT-1|~L)eg^oDWWo3I8{Z>izt)=ot{6iXIoZTiA27-Y$GI& z-TEB`ea~@-cR`2Iepe-Qd7vsFtDW|nEC#Q5F)xc2`QUe9nvnCPJ-3}j-dFP#-yWi7 z%Y+NMqq*V;jyu5x{mHz>CnsG05rTCLS4+2JZ>|$PP#3b+%lMGcv(Wi>#qqcoLPdr) z&S6^ZzjjZC9J}t0A%pq&qLpZ3Y<d-|CT8pT`*n!!)evu^7B1pWgd$Nfp9a!j_GR)0 zWg~E7)@%ArLDi96?ne4%NN(+RwQghcahlnedVE2?M^;a-lSli#*%+SU#{E&C(9Gyo zsbV2jRE@mE@+uv?10@=kq<$Op(=gnZ>ReWz5kwh^+G}yvTxoFr?7o~nGSRi2Vv$?6 zI=f~}S(3jM@p70_mY^{(V%UB-kb{a-R=Mpk1FSFiTiW9;n`0?wJDG{-yx;xkE7m3h zxQOuidgeG+x&FmYpNku+Sod1__=ld00aPqNKIr6btu^jW0WHU^Y=V?`AHumr%xVK6 zN0!gWzt7N#SIi-rQ)pvk$&SSj(^a!!+2z3^%(9zn-ioC6WKPX$7-Aw5=9obJOJg$q zVR!3AEVW~}b|T}R%=l=WV?S9~Cg@1pMGxiep8$7GTTRri`kLkRSiy?1&K)c}_vk{2 zpaNd&rGJGa=~Da^zBr(F+9^J-v#yO>^tDf3bDoX!*!jv%+mY~^(JAhR5(x8zlU~rB zNnb1ynSuJ<Q7AIpDE?g>UZ3WuJM?C?dzubVu5izy!g(^>&vE^<f?QXplGZ_8Iug*` z9?|o8sLB+K`2;dx)w%`J?Ti(t@=ez$VrLmmy5!RocZ+iV96su9w2!m<kHIPA*qX3q z3GN9!Lls?Wig8Y9E4C)g?{WSp9Mtd@<?Uw-2XIFvCa3}Dg_w;RZjPWfvk)s0|0l;q z1i;RHBTL4L0OD8He0>B#L0ZUES&oeg9^2j=M9qb^6eq|XZZ4X-o)gY0(2<~>>MWV& zgka?@7oX>-e|_!FO&ko#F!!07D^!v8rdHH5x85aDq8<JEKq<lQdz!!ZiDjVHoy?Su zb+0)2yl~LI@VtMPnDpIQTbV21aDBsxtM)P)ExXe<*v)Zde&>rTUq}?|r(xu!LfS02 zo-S^cA3yE2V8`E@QK#4Be+Row6(}9^>vwmnG}wF+Y))q;&Co8j^8O94_9(q7M)}s1 zhs%?7-ne2l9++<swuh~{m9&$v{IO%v=ZDUPTL(L<;8k*>y6+04UWz=E?+WpuNWIev zx1E0$r+u+7j^PBaI0AL>Q0&~_?gy`QY(MG0{v@Lfg^G)=^{_a?J#`O>H2=m*){O({ z)fWMJCD;c}v^9|{tMRpoAK$!!6X?~yk@#8gVxlhb(;sXyVf$1r)D1Vm7Y(=llx3pb zh5y7}AB>u*U$e2Z&X7c?vy$`C0l)t<p7Q@cn!bUd^6m@wWKDLH?V4;(HYRhjZP!$j zC!XBNHQBap+itRP&-=gket~N5etYdlYp;-jv|^`K<wn%ThkC^0PMmTF1K|qQu4hlD zHW8rEQ0#0F@6ZVk8bFhUiRGH+J`~*(5k$<fJz~NF{*?HYj~Af87{yLU=s8@Z&<1X} zzUY=X5lVW+SK0|a5Z=YVf~Kuo!YDM^r&3V0FfR^{whN<5@7;K9&_XZX%+^Igt{}DM z&tT{%PH%pKDal+BZXDKI>3V@fo!UUeP2>||o@>rWD4po+0MmO2>+(#gzHq9c?~B?R zGp|fje1_uMVpS^6-_R;(QAfXhjk77&zM^cm>9kR?7M1(*!sMDOHy@`&Ov8Muz{(Yo ztVOvXjr8?Sq={nv%s5Z{-O6xC(suO_J^`<DnBfwRx5=Wfxg>%(2p;DznUFtTuj37U z-HJH41AKhCZn(T=H++bHl(|4b?M-y7te}+yd=5fg?T?QsmvLj9-~lXO>!hpzq*b_U ze4u9@IgVP#d)O8pECuDb(}Z@|FAPp~sc=B~8toL{7U>;j9U;*g+_mJ@YYqX(RUyrk z*pMia)6(eC8M|sb-vj}txyl*@Wq$9?Nmp3v7uZ}>L1ENj01iWPl_#sytm`Thm~Bo7 zo_#)hn$-|yF%%lP9ic^gR0&~DP$V##$Y)0B&$jYzAFd`*JA5y4x1!0o@3u-F>18`5 z)3*cTVmffyny4H>{y6Z|#PfFhOXS_4U=OYX1VZd_7TD=ID&{5^(=HjYG8Hwn0jYyJ zc_XXEM)pGdO>}s&HuNV*Kp?RXGyB`D4!}rg>BtlvX4#RD(&=y?ImYRjNtr{xJ;3tI zh<mj?{@<mZfCcJg1c%=xN-CX+hA#@QmJTH4qizuXH2a<{>YbLBPdUx$N}O5X>RzK! z@`GRjC<SirASkT3Bn%w6bh~<)&1LTihI7(kgK;Y*q@J8@YOt~i-;0nJt0A7PoWPWh z#5%+FG(Gf^F2h>q`w-IF;6+0Ur<BbI=Huvu1-PW3G?psFqLm<BUHB>W=CjYNozF;E zCCFxT0=z0@Kyr(js(+x}YL=|RMBRqrd{+Q2_8ZP;siRcBGAF=xUkjnV1GTU-BtQuO zB3o`Jel>Bm9)Ux*g*IywZD1W&)36VVLzBk))%XXn(`mJ*Z~!<O^Ma4C>MF^2cXHzk zE^+O+#mH`VJ%g7Ge^jhWm)S}d5X2kA)1}g-Iar#en-Rvf=P;BK!~(~pgB3`{OQzj1 z>E~syuI^l}vfktHe7aCQ?#!0<VLz?geeN9^a!Q*<Bx#}lLL5p(-Co7Ls=%xBZ8gxz z=nwE<0w>Y)_a#r#Icck?J{=}56f$smuTlV^fr@Xv+D~7l+ZLRTq!;@Q(U;eED_#0S zu6uL7XXa5i<Tmv+os3S=+T{)XDx<MhQkp7It*)se3FAx96o&+8{nhx#tHGEp9N4L> z|M$_%`SH-E@Co~LQXNOKO`}KpsPv6MR!6JR)#_&Vj9EgoHocVkIDNiZf#C(Q-O=~g z0X{EiiR6#?!n%t6p?34*_MT)?<4$bn`RZhD*ZL;+$4Xlfv1Ql$CUuB1ygEhpbNnvh zy3ckotu=uNBx7Jv^#r0W?C(8SZ1|)02%9+UNhanbocqxC^Qf}ErkG#c{-2%^CGDa( zoh~-&qK)|W&VaUajF-OF6}!=2%=yXKnfOqV4dX41iM6e@vjsbo_RG^7Wqy?!B^ovz zL`09w>I@@IYsK-C@SrUrC%-=$X%yjdb>U7gt?R7OZdoTs$3px0r7M*y<*syH^`OEd z!_2lUx#FRqY^GM`>K1joK{bys1G|9YP3rHLVEBjB<PwutL`NhaT=0v;QO?xms|f&c zoHIAeX_UXo+z#<~Kit6r+&URPyJc+Ime37XHgC4?m}oiLiqB+BPF4H8awcJ9++q=q zt;DFqO)hk(S$PxcqWjrv86n+1YGE?pOQ{`hQ=T1D2KX-qb4t32l*6*;aL3ivb#Mu& zfNd9_KcUEpptsCkyaBYItpg!%n)G^oS5H;F-A5&%FOL(`2dp881zs4}JpvIrR)fT< z6a}X@RVo#-$&@{MesV@zTw;4CCfEu3s7B``;7;H=IvNxqYp7i97!IE?(F-tLXvOPX zrk?I$;hm`Z$<yep&NgTVU{%B%McCjrT|j+|aNhbnn0w0>8r2u$F1otea5Acoq7sc9 zjX8!LM?<`bRVW|JdaSEisqc}UfT`B^DL%a6Y{j?=vzz{tia>gpH;s+AM(-9A9Ycon zE*ex%bcr>FgorjR1`hEmVk5CC_q+W?w@@%~0r`v0fz=1T;`%-|@Vf_k=Ih0Qs&6_b z`*2=^rxUnil)I8UW%Kk+PE6XZuzm7^DAlNK%yGCDJh_=n7gO1RHeae2huFVpZpxbG zaU8pynFvkKAbfp=1<_>q#%Px=h3N6!ZVXsA04#n_;(-Ewp0DcY6dGhRPfSQ!A!6B{ zYX94DH=Kn09joj0VVlvv8q$%tA5Za@(h;(|m?hhu|D{|$G-9w{p#)5ewVxJ+$nLD| zX}@&5i15p<!AKj!&kH++i^O#6dA{WnN!d)o8CV(UkdXJ$+ettGyD=7ue;ny@(}e8v zvHoc@F>zchWr}0ax0)LFa+Cgx#2^?M$l&pL(o%2rWr<mKDf@aYiSgb0PTru#Ao}px zQi;X(^la&}Prk;JF-x|?do0DSn3EK#h#eN}G{8l&--6wSaHrMpO9acy9k8>b9=gJ~ zOh;z5v@9BrST3<+e}FR47R!x|zP~Z$XA6>__D}1xbfGh?KXAe0*IP+&{_K{Dh#D5z zSnAs!dsJG6yue7&LZANg3>AR^tjHz-CiYYkZqvntn}rai+Nln=8j&;Yo|`?4dxf24 z{1Ia5Z0g~l*DVcgiA6cW($mJ#HMzMc3x<d~Dd|k3+fmH4od5a#`=%l$-BPd0y152t z((z*R-6i>^4-S}e*wN|~c^nP-;@jZZPBV9Zq1u5Fr>IE{r|Zqtt^DBX`@YXE+AI;n z>1Q7#(G@##3aw0%0G&47IP+`o*$C|r0kC@nemInFZr3u*zz^kPYlHIcuj+Kh34wOT zS8MQLZrfskM-&Hr)CfYKGT&IGBSS-YKC%S17qv7{1!DReLN63gcNK6g<yR_8YUM2Q z24XMu-6t;7n(uSyg-2;_xhgp><Q2<YAh|_cZ&~5<`8WDZ6o&2*L^<>2c=kyy{n)?8 zJ3kMecn_J*l4*3KTd)yz;CihXur||R^d$IiWkW-oy5PLb1+S`*6Q!&gpt{51%i=*8 zP$ggPHCb;-$jpyXzcsQHO=t3IHsUOOm^RBS6tRXDpNcjK)#jg$*-Jmm;@HG=S=9!^ zF9V_%+t;+0XC?6e$0CbNxdyOwr=H`+=#@kJ+wm5Ut_mfKk969UW<IQ0p0~T&1=LnB z!8hTz(sErl-1<a>pHU-*@D;fz`cD@mX@BbyUH2$X-A6^syp#^E#qsv*Pqpvsz7=Pe zVHHr~IwSd^y*tm&UZ;l>x_*yb!c?x35JZ4&k?ZAn)s7p?Os<s<6v;MC^rkjB8?1VV z5LVjV_Ib7;t0yJxQMKtJ0nTC0rMx~fD-uipehL(Z(q0=?H7&WAw!(A(iSF4>OEB8g zb0|i*f!_gt>~tAwy|5KO>Ie(;X_Rq$n581jIM$F&d?hbJwTQGyttDRRl-ZlA_U#;t zy`YPY+KJ4roPGkim>H@N4nUIX?R2fx*+6m?&S<cwko0<Q4eQ$rrmwaYnO~$~>i}EQ z-Ws<8pOip^EJZOI#~4-39IxzXVPDf4&5J9#X5~_VGi#UYuM~j|*FgxsQVju)%!_yb zT#ZO6hK$i}3BRw#B~Wb}cHKBcF4S}$bF@5im5wq<eFs+j>%qx5Tri%a!cEOgDKe&h zct9D*#$Q;n^NiHBSCAs<0)><{IP*IZCT;S{a9~nokLBIa@jU+g{Xdd}APy2^`z&V> zk?0b_VPYC9x4Pgr(Kc2rcdjH}SCmznyP}0eRg{!|)2)=cM_Yu-w^!UT-jCCW_V|`@ zfd7m|3$KpxC(PrOz53@ces7Mbc}M$e#;AfXUFc<(dXs^s+EMgr)K6P!lQN?ccDOaz zaI!?%7rl}nA-R*2uZRojjsHf|K<p^TIh#)(gO_jdC;1009X#&|9|&3-K^=9o6O9Ux z0OIl!=x(<a9GnGTg(dc~1{=2!$Bm+DX+$Ykywn8<i|6Sgs1E*Xaq_<hF0#Mom9V_; z7yhy3YWg_axQH7cFVL*6^=HHFlR!3P)5b9VSxz#+4>TK#DHq-|V{+*@Gh#+~IVQZ8 z0{$&3DHwmtt7ZNZ{GAMe{J4Guvl22an!BAsh-W1Xf~iy~U@fC99613NP501=STR<X zEfJ})mkvf<Qtk#z4G@+`{WCbNk$wpo7dh6_YA$qlQxFNM4m=LvJ^CCa{3IIMBG<K< zqs_w3{&)xix(icbHb&pZxZDT1JzE%hK@xdCLj(ecL{2OaivH4kPUbRSeS0q~6fQz3 zgRMuNkqSJ~u4tF@%`+R5crUl#gy0XSg=T>@1Y$?)v*hs<^;bs9T+Q5vy}l_h%@E)Y zc-@Ed9k1r9AO$1w7sPpj*ov|k-eQr=C37;}P%;S@-CWZSd!cSb7@k#FpgttMVi0g2 zwRrfLG`ruh*fdcSPns&ESDbj@bztsB05I0Sp{qTa{<X#N2yA&XP)soSF{*=lnO}wv z&Aq9UgONJ~t82KOgu)a)kEO}Fq-cG0PNH?ecY|ERZjT<{>#}MEUWN-@;r0Yn21s~L z!Fdf3N4&Of##2?FnxaO+yqEr^+29fn=++>yf;9ad7O=n?HT^bdyzI_VQ_&`sHvgrg z73pJ*Snhb?lJ@Qt>I1v!q+HF0OnJsfWTp)-ogBfG`6ZGJScu(-UXUJeO~^&(WxokM z3Mlzzrb1kuVAH&OO;RcMLgi&*q1|uT8*(mDeSHF{poa@HcqQOnJeX|Q8n@WZouCTS zs^UN^tJ+mEyF0q}X5&8N{wcj8(j&qJ2Slk_6f0!@L7zOS{!-)H;Epy4nT0LVWpWd? z9aAVCen>A@wRgw;=n(dUR{iMaH<Y*hdd#k#2uD?!U?w+AHzNEhvtY^-2rK1Vu$)m! zlD%#7-#$2qgPyI_|0~enIzDc~85aq_=_NHH>r>=tZ}2YrzrGXZEwuQ{!Owd=9c~WY zqm|G!SRq*mN)B-$CDdC0&>LAorgveK|3Ff;jvy$7Rod6>J8Gj?N_VEXv-I7=i?Bpu zAT%>F5wP^^Z2e9h%<QqGOv?ytCGpI62|X+BUsnVC$**@3;Qk~TIoMX{Yi;xERQ0l( z>g~;4bJug#5cp#OGYtVK8gpSOR6pJER*vKE%(a1bzl#yKAn>_KVQ1#LSWXt^drU3Y z(f)GIWpsF&ylyYQrh$vaoR_IR&R2R>*Mee3ocC|OtL{@p>UiOS{oW<0v+1+gZ*LK; zMCpV~Ip5+iz7StnJnnbK(QFM9lWbfdKk1QCV8Mn~wb$aXcdth4a6T#;nKroL_o&IO z@P3*zD#`i5t0m4>{%IyC^U%$c`b(K!>pyCxHzY?6mQtW6x9je!-RC0Vm{W(Z1t0Pn zT)2@S;-D&OFlpg@ANxS>*cT{^Uy}r&0N?YD@TmJ67TmuB5}E$@!-dlp%^SK@h?PmU zAOhASAuKsofC+@LkmY-l1@lDEsBLn8p7J=S_^>l%aDu{&%nQ*4t;fG0nr&97Q=9)R zmLo_iGG#a>aCsFWQznc5<GG1Hw?>}YV6x@*`?hVVd`r$8avMg^faK>Fn7^PQaSJFm zz0@)_)oy(o{#}Uo8Jj^~8tz}-4Tht*OHzEWLXkln_C-enomSDThda%8Zm!_>Nh_9^ znKbB;3Uw}kBx|+z(OnzFGulvK8ejSrpOq|mkMC>4a=G@qF}Oj2l%$t?X1?}3Do2qZ zhpTX8G}%KNQJz=^?$4ofxe>jZ<9DPbtv?usl}>qH7|KWDRS)J%2Vr1m@#5dSCOKG$ zVLE}i9;6C$QyhWO;33gWsW0nw?eVkg)H>8zTHb{g{Z_L;rms1o1ih;`HY=K5JW)jH z6zVEuXW^|M?aR?QGBiX;%l%1ileWd4b%vB+GUID<dwOvq!fgCSMw~dV-a1Tn<6Ek2 z7!E+B#UQ}k+R2!v?+HJ@4)K`%phZ7f@}l%-2Vs{)qMS$f4+@}&6g|=#a)QY6(V+Cf zae<97x)-KC4_8bIBr9Fyloe*e5@AxIO+r~b7jyE#Z2C!51Groy{ybh71KW<8gbg_0 z&<d`%%Aq490b~+=`>f8@o$}7<z{Z%^^cAFw;<uqC9;&UvYTXw!)I_Yg%*F}JD^EBf zo7YUVh*A2Y{SjLH^`|S7Lrn_&*JUzUCf~N3_;ww#=)z%#M7~*k&!yG-=`_V5t3sU$ zRXdJsJ`MVg?S<sI?-tn84jIjr)m5zTdbt{_QFB|I&Jop3ZB-3l5s-JD6H=#O>bY)y zK=VL^!H~IyBQbkV>I^YDGJ7sE{ewDWlhGCWnOm>L&>b>2)hh@`j4NJc@U49>?lRrG z8u^qVaGgv!hf5sfY@h}sPtKaA2cXtRTEo`w_huTEc0z|lu3{0QbgVuI$5}rQwq+xR zSYE}&x<WhfWPy+p6LQkk(9uvr>bIHoBu~2-a49K=7BQ%2zr{N$_{g0k)T?o?NYN-+ zcp%o&@x5HMTbt4<QIDOZ|Bo(~jSJ$4T-8}qc=6i14Uy_`)g!B>uWf+WQntZGX6x3l zS`?QdmkNqZY7pAmk^UA)#A)FIWWgQJFnjK(3Skvg!AZ~6%n5P0@ac!|SOs338fJWb z*<c83YRa$AGP^+vYGwEmBzuUG6_EaQ-mGHAhDPbeV-4kBDlSPvLhw<CI6gvM)58zc z$~D|Kfddt!ZqM4VKn)X8J3<ruE{%<wZtVkdsS&c373M<KtHvKTMn5VUCRJ@Xf=S{1 z-OJUz*HusObL&u!krsO6#RpchLcL{>*gf7?JwP2B`sshqG83u}Hb?VPvNLX{O5|PA z%V_xA<hz$IDD~L0bMm8_GdaJISBO8_LSK8P#mVITv$$;_7vOj&^z}Op0$WVj(jR2X z;@oW|k1z0YN<r2I;Q?Gqf@JI&(1U!_H_v|E-MEYxtd9X$fu><xutHGekA1c(2~oYA z4;9{;uM>vvx-O;q>s%HM%d3!4KNQbUN1og}(`XW9dtQeI8_J(`>@Jmsx?E~h1^0ZK z)cDQ<{fG9EdwO<jNQy<QSTJo*Rsdkby~h<v?PA`Yoj0P-YKrS@GewHNPeE_eO|ii) ziKL5;k#hh+H8g-u3F|k+xJ5Rg;t`vF-16#o$p9=g;7=8BdnfH^=b!s$8M=2vF@E92 z*8e`ewaZ6#x&J_9pct~<#n_~R`_JGOYW;roSfC5XR47dF5vYX>$qsG|sL`RVemut! zc8r0Q?4K!lkW4<J9=5!1>M2kBgEpUd6z(Ei!D$D6tc|pB{Q20bS^wMs?l(8`>}c~- zV?)rbtQ*H%6Y`hdBL8=yO|0%o@#nWVhqanM59b^%@QP6Y)#?oA0y;w1&JZ1hKn1hy zmj+;BCbMzSZF4=JEY~A%!y+#?x#nWMhTATVe}PxoKE~Oosg`QV1`q04h{x5|sMx{~ zHR+x-gn?-7^LT*Qg%HJ^HJ;LYo#qz@aHpEE_&yQXKMwW$sU6xvX{z5%Ur}?VBymCS z&O4TqyV7oIR5UP2oxv9S+&{{;BxL=Szn>$t?>q)R&oa(q^Zwks01Y1r;+W*;>o8Qp zkae1ztVDPF$R(tSjQPreZXT;6A`o<i=WtB3B*e;vqRoURSHY*x*x9aLaru+aanMQv z@KW)0%Wxx0_|39HML2M-O8*`Q?{}BX5!ys!;4ygtw;KJ}feQlSsAdvPy7VmM9!>&e zA97_CjJjUhxw0sOkPRQcS;AM%x<m7Sn5c55baa3caG*rk0inbDdAd=!+2*w8fyS;l z{!I)Nw$`#cp%Yy?5kv!295KVr<q9bwwpTbEH8s-rkYWBwpKqckOhawA-A#Kld2q;v z(kl?zXqD*HSOfDjcWplpx`=1u&}@639H@9k^%!<59f?Tb&rBk6ODub_lGO0)g`aOb z9r<g0y?4Ho5g23S=d3qgL=OrAEhPYafbNLVU5_)-_d*@8iV9YBdczmHkPh-RT#_Vl zo8@k!emEwCZ)&ZXf<Fsfg8V`o0mp)ADl#R;bw{qRj&p|ep1#91$3M3RDe&Lp0y6fL zkqEB(YjFP~KJQM)3l&`+OY<QY6Bde48y!dSn`2?zykekEMmU|BqL6~^nP<r*;6MiU z_6y_~VX-aMC<SV5GtqoX%^_ts2*$RSOd5-{mm();FP<yv07$9EldY@+iu<!dJg3P7 zP2Wk~F!b2to6VFgff(-ekIAf_1IC<#Q`VE%5mATzBIGL#8BlRIZGix}1g1yM<={q8 zY``K@;|nOjdha!=4W}rZVS!<F%!#|Ai@>=QB|#U`F=H^iYR#T;at&aBrc7+R9SxnL zft@Hk`IkkYE^{`63rjxqFc-O*N<uP^lu=^H;L~5DYJ@rPOcbC*?1S)exZo2#T?R!Y z*y7fb`*~ZNTj8<ku|4v@Ra5*YolKc~tA&euA3jKyiAAD14a%|Ypdb;NbUNwH)0%Bc zXTstD<6Cg{98*0HtorrQDdZvF$XAV-bxCZ7ug%O~S?L9%cElb)$Gk1gUdS~32>W}M zbPz;Jv3LGlIcaKXR%+0!K1nn(qENH3ax)_D==v8B`)v46SNqfzMa~^UpR?C{Q-02C zjpXHMI^V!&*s;X(d<?DIMifmB9q;@&^lY({LcpYc@F_JLigII*(Mg8{#PN4U<`)fB z7RXhVb~@Y11<L|C!PYbYJVVji-B?wWR>3+$cS2$0NW^m;8~qyuK^ke8x7m6hDOe&S z_dU4}nBA;{jz0MRSpa`H0QeV8R8AoK*-LFLJACe6vB3QU-={Eii`23n|Gd=S_pe++ z_+O*~eC(D;ze3(S7`__gL2{~E#skdU%w?8kdx2`*bfJ(MK5+ed!ZLrbNtBzaMTL}P z{q4HNmw42?>M8fIMPA2alH+#!AQA^KenfPQ6I)6^%Ei*=tUE#PLmD=|Qh7uB?gJH^ zoakW8S03YH#RH^%YQZY}@xI?y{pcDc;<>HQ1H7w!-RgQQ9O&pOfo{;+lc9ql(R)-p zRy-1E?B)dx6_vrfEpt>7Whm#R3vg!GMa5&~Dpda<7qx)@(I5Nc?7=vYEiuV~D?S?B zyeJcgX>5VGa?F2EDTvtd@`LQ|baj2(FxI2$h5O8<&raEp8VvgUc)tXVYMHKP7RVA& z%XlS=MDfNliLqC$5j<v+2RU_LMV$4!=`wn_%D{Mb!Rn>l$e014Rk@zOW7F$({HrzI zPpWZ>Ll%i|1tFtz)gLcznlhH-aB+L^NJMC|)|;RziEC0LaoeuLzl`O@>@v_OzU^{1 zIjjxg@X3MKO9U`-*f|C=#H^CF1Gx4jw?}uP`Uuwx8e4L77I?m`U<K0(FO(O)&<-R0 zu)1{LKFX~V9_<=~g_`B$+r&zu`%d#LPxc$eSv60qs+)qHf9J9T6+c%qe0RF6FGqV0 zrK6QmC+q9gm!L>t1*CtuzhRiqq#>DPqp66eV+zNeF98fV22f=B85t;51Z$G&&=47J z@|Jvk79zLtjT|bI^#{<*Bp<#v&VdXKbozBcyn;$Mr(frJk|Y2<P(}|2qYY=^Y8l6c zSr#+c^ByH<XwK)NVKo5pLNm1Wc>Yx`++PKiphkV9kbnE#W)np}EExp^MGrE`AO)F; z3}Yq(aq5r@3SWqHY9H2F(;em6)71hI<yWbPJQxbN%Z1_QA#|J8t-OFB0PU}wdOwR# z6UX`G*A9eJlZ`U}vUm9o&f0L1EDADZ^c{=rRl<6@0F0Kv=#-_ST7N3E%6eH09+^$f zO9ENc?&@C(+-;~Njb|KLdujWcqP`M_b?%`f&}|2Rx<Y@7fC67fH<gu?eH-_wg)o~h z6F$?)Bi#-8`Kz55_mcUwKK>uLO|~01nH|Cw*&2jkM0n0b_*^yM&Fjz0T%lSGo-NRB zW|XMhdsucz4QJt{rl6-&&m-JK3+bG7V^%sj9Jzjqn9RKh8r%3jLZ#kvOR2xa)NIGk z<3ZjrNyKecsu3JsloR5!637fzAHhgQXwCn1BQ620WPXA;ROB5WF=!P2M_HR2Z#Q$i zSm5xh&v}rXqhe6F7Vlvo+SK_0fN?4VpK|cW;O^+-=+RCO`#x5@*;95D%k0XKv`3TN zyJQ#F+6ZmpohW{s8BeEj`ZZ*xI_&lYMVXOWfN(*4TZekp)P<p*j>^;|g-$%!vtklx z1!MR!K(J)eBJd>4Mzf34caLaG*&Y^pztyhCxr>YSh+4#zIdIt-%T=bUny4=MIl+!| zM(FI>b0I>FjpxJDAaS}(HK{RoN}sF#{&8)qbZtZ!n%+x=TNNv2t&eUfrG+KM#jFqq zf8uA9#Ux!(BkvG^AOkg3fR^Zl^d(G|53uqqk&L$}w8YYCukexA)G0%+R;(ety&!>z z-4sJ-;##e+e3<-ma}^jUXuSygAlsH8XR)1r56-8Rb$nS`?rOd(3$;G@7F1d%%YgB} z5Y=*q@JmkAz3f|!zZ5+bc&Clq8i^PKeaKpIxGmz>IP^zqiwl<fc)BK{rfSf0<a&q9 zu$yEvLEEv3>-G@Kk!8Yx13Cy`ABb?>V_T;0U1)hGLqF&1hcGkA>O<Ei=e_c48lN~A zE_#Hi%%!&E`?1k&h;Ka~I{n)##M4$@7w9vT<q<(>I&p4}IMBB{#_~%ayxl2f#3P2z z%&81eB>sM{++7!vKUpgW@$+f1JF{$S7S1MT!u^iP#Ol4?wt#e{n=tStuo3l3&qI%> zokg>1hrvoy{oO!v^#p?yc$E;~5nxEdD;dIhcE#MYGpI}Dtyp}j_@#KM8eV1n5EO7A z6@#}k6*u*8JAD~MkHFW#K&Dsi%zr$d%&rN4d%5zqx`%_N3a=As!7GIzPW8v>^w~zB zxH}ag^mfzr$<Pu5-x>WB(5H%6Q<=K#H2I|7h`Q|qH7c=-(uPI#f;y@)#FL^&NR>GD z^?LyEpcq0s7*%3a)bvIw+b>n!j}o%sW`SOb!gjdYEMDaJ+_TFxR;|XD-!2tdm#|}P z>7g_$4B`5+R&kK49h{t&u2oO`JwhzPH5fr#-@L@#42@r=7-DpM+gwf*J=H!b&yUyO z?d@(&f2q{d+XD76sK<9*YQ)PtetxSVZU2exVx{0;sGNwdl~G6$qk&&aokRG%k#n5( z()1vB3g7Xf%rE=39s{!ByX<KoNJ&g)Ci%BcVQ)UOUFp>sHKg<H0UOD5HADjPu_Zy% zX1p7|s>l*01Y$NEwCyAn8I<*G!G#kp)hz9+pwLpIKjV-Ja4^wi0(Kuk=>had=y6Gf z53nr61CNV}ENVgRg<m;q3H=I8`Pj4LZ(Qm}oMfxe`oE#MHzTEwtIK0Oh;GXzYtP5w z!tqNdz{jQIS1{A7`%-4+T^nSU^^amC#mkkw+s`xQ_&K68r-WZ?7}iPXvG_Z4Hukir zW$?@GRZJ-yQ?6!{{uL<umk7~ManPoOIB3@iN562rDn<ZnY#HN#x=X#R!mdbxr5bcV z#oeaNHK@|AsB<4FV-j~O5rFd1JA}>Glo{LupO(US`wO*wK)9-Vn$HnJ*h_BX>`l>e zT=1u1V4v@-S1yP>E39m>A_TdkV>P)nG?Y6QIQmJ?)&glM0rhf$xdcwqntyt<PkCsz zLNOC9L*qU=d{HYoTXDCi0D=<Aq1MDu%e9}5yy?BNDZQ5SWsZru^sJW$k|Nbyms85U zYK<hEnOI||0Ei8>U^&e$z&BS&?GYj9#qrIGfWT(vD<y*InqT7t(!AE27d0*-CeU>u z{ESL~4%DeF<yC4ZFTBDz@-8`qv+_$2YuCm2(!g;u+H#x{MiL;%-~^IMh9<pqk2Tak zab%!HWc}U%p3$Z0C0?34-eGBp$Ba)LM);y$p<2}!@4K_L(dzfr&8C7@X9f)7l<npN z?pAk$aKT0(c>JRC6Zx^Mlta5oBsIdl;o9#y4BvGhV}6L#Z33GzE>*rVS7R$TkfGhH zW`?6ny`2J3|6&<&#>SWv3rXe?egX6Noq3Vr>i7-`?9Hrw9E(A@fpbkY<oljQ`GE0P z8Hk9Y8SigKEilX*oyp)X!f|>(!G3#6*yDi)g&qm-anRjQ9qm{{EB$S6p6;e=#9X!l zsH_z}j{sYnEva1T2Q#J4&mu4A>;W5puYD%dw8rR;6{{8Hdr=ltcQZD}fmP1x8l|nn z-TUWfT<}GX%7k16uX7z}P!3GFx!)y8`MTg~?q0xlbr>|^DD!EWIvaUEzM)5;6Q?_z zz^^m1Ju#B-qys;$vf`-#5~~qWHP=2WXw+7kbxT}<Z+~9I3U*^u&(q)cW#sWDe!z_j z$2qKNQ8+hYXX!mMe3k+W-4y|jOY`Em{WNx!XeBvAWXdLygKDX8=U<0#%EqdfX|G^b z1^3C_PaLYHBwAjA2q~0OE%jV_iEvdx4pQ_L{H}DCH#81M*73sSj|!toXBrW2fIyMZ z>j7+oVl2~%>&4fCRJPQ+Yk2iQz4H=7@=s%;AcmVXgW`|8EJ~$Rq1v3flcNbHulxF_ z@UR_)K8n?hivw@LVNII=t@4E%oFYx=3Qv(Pue)@~7K8VJF{Ib*fs+iM#Xf%6rcj@D zBoF{_h>QxtmtYzV4+z@Nw@Si03BoO@PpLi##C6#Z>yH!*M4FMc)kujkq%S{yto`+) zy?a-Ob^5G54ZYBI5xrPi<)QuuG6=GS^Yp5JT#mW~3Jl#29>J>Dar>t4;iX{Qg8^5& z_LrcSXJ8kqk~P>45bT+$`x$we5oZ=Xwrwa|LKHgt%Nf0TPr2=9M}2!99CP4+@AeC{ z$ZuCTbXG^ALp~P<JXL*luWzDh9x}SKT1Z^l_vWt?U6vHM&$k?hJgSF0P!fblm42wh z&i-vAS&}zp&jB9PP!75s1k|r?XKxFbE?s};&xAjZ4;7HLcItP*4y93m)1jvn{jJo1 zHy!bGl5CHe_}X^DN6a={=TkcJdC>e&P=YHH^bTGs(ZrAy{Q3{qz@99I-!xtfz1-xs z$Z7A37qKGz35IVyZ`)^;R)+v+y8s{ToTU(00p44-w+V(v9kD9=mfKD!r7YlDKUn#* zZ*{S=|AQR#!d>--Dd2YgqXh0dio{|QUQHZC-V?zG%nqSiK_=`->vXNusc`|psmmY3 zr~>;@u|P~)jbdeB{N$~bB+C9Gty&hI=dYq~0=dr)sF>E^c=Nvma`CvCj+#iqzZ}1u zzh%3q`rH|qc=b-eC|VhN8eJx`31HGSTYBPcHhL%H{3_Hc<E%ZICm|X?Qd;(IS3S-I z+^x}6mMH;`4E#(^uJS#598R@S9Z1#@-_wYbbZcRGK|8T@-EyPB;=flGaXFJ}UIj%C zuqUAl(1sFGsowkY*b&0!uymdX>l6l<g%Q`ql7GPz6S8i?@Bg&Lu_0ap!Tv{gJMUhE zb;YV;|BFytn}IYKpMQzG&)Nw8DmFJjW^#e;u2@WVRk9r|{9Z&g(hw2yEiFi%(g4bD z#X6D0Ij0S}6PngI+cS?LNwzB-xaxS{lQP9N7#}5gC`rF}<M?!yyENc%1U7Fap07&_ zNPiM13V&p{qe{RJ5gXltuElf*A3RKV?8-EHpuOFR0o|9+p;G3Eg_;f<ofY=#O^_#< z0I)g_Rv5+gPbRzc%5fS5>8tQM;T!M4&lF)F4fg2}|FHqIeg{zJQ0_B|g$Hv1ESaS$ zyb6!hz>NqdG@eb?StfYJzaFiYAcP@a_6ZHGD(pB?28G5m-F|oLeM-WTDuW?1J4?6b z;~TU&L)7YTupOxRnQ`Be>q0#5Ck_%q2Zuu{Q^Tp9&cchDq(x;@$JWnXCfv;JzHU~O zFd>Zl25Q171>|*qpQA{KhQ^Jf*W+W_FE(xO+iqpCEYwXFVGo$4)*OVLRNWvX^8$@v zluw_yskp1kf;%A~nr$bnnfyvs>A<Bkz^y=;=e%b)66694R=uA@{J><60UU!8wkO5i z{qJV*wdDU|>eDm-me&Ql%;cenP_6xs5Z$JyM0FNVoY*PRNdw3l&!}rva|OvfqkEm| zlpmCn<`S6@W0;N#)v!}5qFq|szZLSc12RtjUvS%_5F<F2@Kp9c&uos@Q4t*fQiWGX zUWWX5i0WOZcC-t`|7P0O#Vo3Dgp-Xs?rUUN-*=l<meXjqL*?vLcP5j5OIQVHPnf)> zDuA0O2i`bGhE@n>VDv8Zh=#}I1<f7PMD6gvbr;?G(y3583eW=fzDWc~!L|F{6X5+* zFle%Zh9I28^{;nuI!WGI@4U~fo`jer17jE-ErCWB<kG51&080q_YDeQZ)~U2aLI9- zC<@3fI70WSaex557Ukzf+7x+8oS7yEFOdR)fV0^0C0g7KOyE{zjFEmW;W8aH0z3km zo`8#hEF$(KIjVB5L9kSjN3X|&Ac~ZnKnb^aRd&YIyq_3|dMiyzNG^F?31O@J463_* zh&XZHb7vAxub^chuw@ZfQPcyXC1$!6r)@MQhEj^O1#Z%t@oa3FHOyo(k3-wTC2^MG z&%oK11q#TE=3%0|586c!F4;k#s`6XERhl}Y`xlg+w#BLi*>O#JnpwL0g}&!rp`sdW zxg)Iq0a3rdj;2ds8Lw+G*xOfg=`d{DuWSpEf+#-okh-2l)fsT01%EBj7quidZ}|;6 zQTA62?(+frfDPn1`V*Bcj3mCE&IjW}c!>=VQKHD~<|O^Q-2W7HU-mm|6~qp{mlc<b z3l9(Y`J7&HDG$-jWe7!bdQ#w?j=8kYPHZq=g+!c8%KSwil7SCK$xAeZ;LzJy`{;qR zwyXg$_YeVVcjjK-f}yT<3yM!QcI6h{_&1qsl~@){VM?#=F>ILbc99Yz9$?60bY(cF zzP{6@PCoj0@~H4Se^>okW7K4f#Swaz+JAyov#aml^%8%d&h)Lgxh-B-^mZ>JcEt5w zh@T9Yn@h>^qy32G)z!!_IwxkFF`Gb3!)GCC(&)H^w?mBIu_fC}!jD%bsZjQ!bB#ew zL+lfU|6@-A>mFBDu=DxTWxD>Kde4gQ;44l`9K@Ah)FJX<PIEiTXS=>`C6Q|yIn>ma z?0p4UbA{Lci5@lP;V1VDc@b{!YH~$Zv;x=~fNGUI?D9L@%V4DKGq^Y%dgI>4IF>wH z9HbCbdb&nB?~TdVV}^Bx9p|65YIZe+-mEc?(J;?d-7qZW?sTiyT4%U7Eu7_rJNA&@ zRNhJyzNrhf{&)p5`wu`1O=1XYMH|MVD@xv)EDhPhre98gOjJ%_f(9k)9IciOh**Iy zL%EL0s%OFCPdf;+QMJ2mnJOmJ2KDF~-SH`*FlW+^9s&TVRgRsJtBERP*1QF##JZZk z$3J}F=UaH7PgSwI7$OhTesurL6H$cd#iT`^!lW^6dH<jzdCClKQ6C(vvSXGUn5c1< zQm(7VjOlV?(hW55;Z31m6N(ItvOP;<76<lHjv!PMN?p+I&K{joxpcqqz;*l`>(t+B z@8ny8;f{_I_n?m0)c(6*gOoh__`t~c@upV?KDVOabNh4^=0U`#q20`4$RHRu$8t&% z?lH9U1IT_|Qt#L@%!nyK+O--1`4=hmUUtd$L<>z0GQ`UsyXZD@+F6=F$(yLIuzlmy zKG4cQw;X#XD1WNQ<5BnoOsuXVq3<pEm)!Kl#s2$-L!>-<Rg+f?(iaf?j!=PyH=emB zc9Te?=u=#i@2im*a!VEc{0en#eg}3IeotzYGOCKU-DU~dYq?kb0**E^eC`WJ$36w{ z2#A^UuvM&%M|k5cuHLAHT$rcQ#XG0>XGX7oh{xy*D}+4S)jR)*XK)ca-~XhV<wXEz zGkk8P0{q)+pF#$#$u?tI@@KDh+%$VFmrk{8hcTnc>0!kI4$6JZbb3jnD2ofk=Dlkj zgAOoFkbl?rAl4vdR7)(8Qz<+$gan+P(>PigGPSsmAp3_V&SZ`khPFM;RLZ~|L#;P? z^)2Ar2LiPg?1V)g<&Yx?L2{E@MH6XD#HWw*xX5W%GD1+6C6Ehr))c{5M$<an>AL7; zLzyqECNx}^`rX=(9Q~D2C$$vP=b@6DF7*A?MNfLdp>!kVvCIx^4b?mf6PV}{87JA$ z44m0CXg1#CDVU*Vi%Pcs@N9Vt@r#n{G9uuiInIQ+Q;Icga|E~Jw1G`!nK%5k)pb^1 z+rBokidmza-wA{G22q@%L-d>g0&KOwQ%F=jwOE<6zTaY>bFekv<=y?Fio8T*F%MH8 zYz3T=*jdZ^kTRR`CKi~POfy1pf?sB`z$`PI5zI0_NA%TDtKgND#6T$ERd;>6rv-b0 zkoz`fsu(dr5Y<e9>@f84!KPW3D<N0P9u<2NCgpCk;<oP*%(hE<NzB)`YhMue>QK-E z4C2C|Nm0Gnnw%Tz#~^dc6o{(5^jCMxFdxUZWh^G7!W?0)y>SmAkq#APi&d{?Mr5?+ zvfAM_Q6a&P*~O7e;&%FsEh->Q#+EDdS^O8BlRkMu@<EacXxCzx+`fA(_h$zSbeL*l zklfCd+RKn7L%py{+1>5102#ED5}{0)=|EkSn7>Hp0HP2l!iy&2EGLtm<faC?+dL-v zR#2K?>41yLILE}us2cc23NQBP-MaWd$MoiG`YBe`DhB%4`1;sKG1u0sG=~=%{yQ%h z8h%WLbmaX@AV9l75w>PvOqd&YwO=+k&t`EjP9s7p`}YxL+s6uZm%FL6*P^YBkW6GY z-Iz^ki^F--QzM(uD5PdsFrz^@S8t>^()IYByR9FYX2eqHjnl~$tDc0An(kkX;zyRl z0OxvT-*`IL$!T8X<0b`PkaxZ7?$-hD=WE$~oT-vaR~ldQn<cW0(LWe9cMvWZ^nM*X zhBPJUWn#IFKg%$e_8=CS+WsYceBZ@tveX~}#al{d$lZ(<o?q~f+FYuM0wN;6z^&pG zM(6U}otAA`h*cd*E*`=P`wUz?)IG@mzq<Va)C>T`?Vyz`TNkppTB%eB1aZ*Wjz|q= zbm-$nV#&Gz2-d!r$%aEK-nFu&R61>}P$!U~pk24323;n&KjIu1L0$A?vmdqQnTAoh zHQ3{8YCy;=-)S}mLfjs610INZxh_YFR2^R>_(4b=@S1iU!KxJ>Pp-L7_h1xKNRK51 z{_bJHz|$o8IiF=*X#+eWp~&&&VN>O4_@%6yd7my-iy+|;6f{FimhI6$s%$Gdn=1Eb z+eDxz(P8u+*C&|O;tu@ostYsYYNzRe(-MsGVRt$r`E{ErFl?_FKItpAr|lut)7#i1 ze6A*3A2>sqGo!Q$c9)uTz-M0Q79;5^=kM2obU(JvlIdU6G*5adl=<howdt?Aqg7MF zZ?@?UIaikDG&0p-WCK7%`1gnQYb#t2=akcix_0sV%?=$zr72dSoAeN`DmB)XMtOh0 zEq6pZ^$2DJR+@<_zn(tgcnz8<5d)H|Hm;#@*Ie8vCI9ROPYrq_%CTIVdf7j(lcxwD zbGZZjy0;dIBZ2>6lxk%r-&^IAr>V$$S;ky7dYI3?K~%89^p`bMw;V^4PXW}N*Rg_N z84D|^GM609;v8s(N$ac49LwQW2<K#=10<!57Dy`amCvD+TYs+LrQzTSOn@%(s=%4w zjxhOBB97(l#tL?wuJBj>M^f*=By|J>^4^CMnm!Pg7W8xyb8B@J48V>^(mckyGkKYC zhfI$z$#sFgm0nEx5uW(6EiL8K1&7FhpV}Oj<}1p9<9THT!YE~@jWbSmAx=2Pi#Q)f z%C{3cP?ZFz|C#UUN@~<o%G_U3>7ST9po)z9Av$C7w@f6|@NKqcX)Na9uDiI=VJ@#U z+4_DJEZbNhC7(9gw^`bZ`OhRvf_DW9@HY75W6gi$5s-^MZ`i|9cW3H+wZg<LN}UY5 zsftcr;I50UlPI0)#NV>=1=S)?VOaK-(F%>9*GWGj5Y(fZVddQdxO2MMiDCR6!@W)p z;kYCxo_D5?(KzddG97GwykNr8x7F^P0~So@irq4n&Ee-KJiz7~*nvev1d+RF)Y*QU zR;C(*`AwG)hSdcS*`g65YyW_>v?L~HF%yfR0X>e;AWtdG|ND~+ZDc8I3kr?2>=r-b zBbJgu2vsg}jBC@wsfE<1JH&Dca>J-l_=g2oZ#fak(vx;3Y#kCu<dB9mso)sgyjdiK zji%Y@^~qk!@%B)NE3V0vzo3dr!16C$@H#Z3NuE0Womc({2D~S}&Tp$Z@6MO^0d$Lr z4vAQ_&Gi8o_FA_n(sZR|-?yb*I7cxjo&h30D=`bMK@iOJ@VpF566?Pl*sviy_gnkW z$LZie`a6I=P2>CNQ%;HB&oQwB(k`CyyFQ1z@#Ok!4-IJZU3V|2sncbGD-A6@taqnX zu>V$Xe?vv+P<*15RQ*cfg^C^o;<-j&)!1ZOJ`$9~0PY?N*hYM3H<s6@5!~?YeHFD6 zXB`boOG#q1Q~5z#X)b;VPlInx{XtY6v7~yw@e|`wh@1hTN_Fy7z0fn}Gl4CW*Kv#0 z3w!xMw;>zuG0Gt}5$@-q+Tfdn`D9hVQcO(mfVj90I9z78(~`FLdGmFR>wUd<omb)r z8N4a-2XSvJwq75&_oUYf?uGn2DKj=k?KUwLw3LvcMHEQCGg!i+Rrr>pR2Cfz*EvrJ zf$T7D&|3%@MeGK;^TtG?z7vbgQYg8SOwO%4Fn<1%{@G${H`o~V0D5lgtEcg(s|CSF zUGb{Q3j)ID#myl_gpvTCe|y$;OWoDr0DZ{S_qTDvVV>Me=<aB3*P5W%d_$Dql*)i< z$o3M_8hHg^;J3MRlPS*-Nbf9q>Q2yhqVVq007d6uOkGT~00LUZlpilum_gj%T#-X- zT*E#i@cWxjz{($V0XMj9Ju5=f?(f)xsU9GQ(XoR;Z}08=3>va<gI{HEqJE9){^tL7 zX9KpI1vF3EA@BI99cTqyb{o2A=VhhxIbbHXnMg?dQ11#T;;4^wFlej4s4%Vv!vFZ9 zm5M1#jI=ar(d;?R66S?}162VF5TVjNh(jb(4L6N|V%<cFrGz+Y4X8g#nkwi5GkKQo z4IdI?vH#L|`>-F@CXau&h)$2Qnms<%XkbnsF9URt-R~5^U3xD$mh&9o3hx9z4+Lpd zQTy&n37}WkI%i<kx_;5u7cnBzK1Lkpot!UpAlR!73~EuxKASC3f}Daj`gykg*Aqaw zH&`yt@JF^i-WzzI#go9U0jw_=E}4d)zSrNDnOi%?8+-iw{5?<&aGaX=Z3at{uB%e9 z_0Ua;8VQ^|L|Ak^s0X`A7spja7N2j8QH?m!Vn?i5n*VX6v1LwSe<$P9wPZ<7f9lz^ z(cb@ru)pzgq)e@wLEP~9GSu`v5NQGNS1|QgzV*)~kaS%wslWZlRs;$p%?i#eI)eub zO}ERVd-v{3(?J7r7g`aRKfV1zz43|DHet3_9w{-s8@TxwJ5H5od=}qUq%F4Ex_Iv` zEs$b{?j}ly_`vOdn}REKhf{;Cn(uTlw`n(!zK`8=w9xd7&8l_(KMQ~cflIvS!MiNv z{3y!@#FhXQGGIjiuus_sL^MtT%;%LRphW%&59ODU7@t_yrKB7p+e@M2*zQSI$%#w? z8dbWg&e2xE@81in++O=S?Ge472!Q?Ide%)v7-7}%tIdD)S(Ho_s*VS(4Ofc`Wgv>I z*g1xK?~8*ynohU5l!%-sb`N{Bcjec15ciGLN0nPk{G<F`xt~-L*X#@&cX=D(<}gXH z;4?+RcUl2j_if(bqjpH5a;Q7Gsu`~G?|!8MRJxY3$_w=gC4SaTsd{fKNnhl6-?Rxf zEv3pNG0Zt81}HjIFs|=8nj$t3z$xs*83tp&C1rs{{S%aiLXQn1tK`<7a#Js#M<0Dt zAJ(nyS7mF|TMXwN>C@cB#1r85$>#IjkL#vng5*!HT8sOEyR6ugS%Lo=>#n-vv%uR) zxre(|WXWh}B0AK4$k&*RdW*!;%~{0^M|#3rOzRk>NI#`)d;Lsby3W}jhpkEHkcqL- zZmu)D?mHk7kxUGPq?kf**>b%EmI3M6RK1q`a_yuI_|j+w4iiTK(T@+kaD!6D&1y?s zaafU4m)bmCdKc&otpro}FGu1^8=ecp8J&XbGfS9-Obd}$eH6mspAMhm)mnWsrHsAt zeOm2{$6_@XzV51~P#mLQ9&J&MY#J1F`MB{4Vp4{Ba8p~Ho$^y^AFhwbTzg&@^$<yj z{Ai-xV(?hhacmA=<h^!|I?^itkuXjY3+V~e2pcjG{e`_>@tz(o{_&TlY?fjpZ9NQG zUwkiLpW+N?J&>X4fugsWd?G#f5DT6+;sX}|D=hHFfMFR5_yyc`sa>*c)55obnWx$= z0#JE<@javT9efM^=J(zQQZ>@}rCDi<_;gLiFoS3$FHDZH@#ep0y2TUL*7Vf5cDne= z<e+JD(zKJjGq&mhoI5+a81AKMvJX1rjul1qu6zI9(tdZhbE508UVjbeNIdI>1m=2O zJRhgHn{3r5s8_L0;D)WM`;NyxlOcC8q6-L?1c+so^tiJd^#o+S1B}Ca4bhE-Y$?CZ zz)5YM3R(&pAHm#9SCmS^6<CsuE5+r-CWu-(sPNp?67Ivla<>bTejbvAk4LjBC$Z}8 zHM1oT$)^jP3m~D*cv%PH@dp%BHLE>sB|*#X&9^Ua+tch<`!$-|->Kp%+1evhRLkD$ z==g^J{xE9sU|!3_Y}FDKx!?`bXf+@Cx-3@zGG92};6T`>w?IwneEP>hI}No(2)ph? z7xl7f2yejXYoP?d;pS(fv6_8)mlMi^8gEuOt)UK`=VO@LRq2JUaXokA5op!28>w#S z^X0-u<C9En#!K|5a7-|-Z(ya1`11I*K|%0r6Q{6ZDyIA1W(y)bvhM117QzQ6%#HYp zhxjPp{_!BV7<zMtGl%_rP(AnShv{zyzrWq<Qrf)u)%N-bbn~O&i%ZTiFCiSYvg-?Y zpHRT(ib;tpSrL44@E`*{egyykf8;E3g^@Jq!JgLb%F+&vRCegm;e*)1GDn#4bHT{1 z!S|++XGQ*%>fxUXwcmTz!)ffCo`DgB1V;AF`*5nwUTf_hflg6$4>n`E9SKUIRdZZ} zdTGbnT=oN;ELWU5VOCqu!~M24w<5xCtIM?IXD5r!BzmKtr;eRZODTv`UVK#$f*GTP zLaKb%#o&p_4zaEe9uORcNzDZTkegkHcC5PEfh(iI=Q2?+8HMOCwLs32$T8$`LAiS1 zz*gEBNzMt<#HTh5od1)imh0rvuBz@jplOr=2CtM^(UBGF#=vfVr=^81m5HTyvc>Oe zlM~pj3rnMeCznWo);)>ovs04>+<tDM<5A8G4TL0oOqG(;vVYAs<2<ADA`#z`ZC>yx zAe@lvmZ_3?<N*k{n+v$;W_%&_sxo^NbPDleh%C#vqA_vT<cHZ3(Q0B-dZFf2oXis| z@FO1IppbQj22ivR>hZTiFcTBci{%ruBuCAK&gPh_mF7DV&y7rFV=ID<f?N;Uwby^# zkKk$RvFg;9|7vaod`-5XuD0*0Kzdc9l7wwVRMUGnV>d9>bV+w{V?3`iO~Xzou?}?- zo$hklZ#U@g`Z&)w(mwxg#|6xFCK=%CW7T0L+oZM?-uE0A{t`K=eA0r!v%Ep}O#?=I zyCYh*&;xxtYZnO$b{x%Cs?Rl`dyB+dpZqW#R!17dVDzg}fi8)|7}N6EdHp@#@1XqW z&-;Axnbn!cxTb5FSBJBVJ;L15xA9DdsM$=GZkc=f9T=Xm8t%BaZ&e)NA8=c-P<n85 zn)k+VEM2_qXYzGhZLO(Wnpry|*;{bAuKEtw<zVz^v%w$PztU}U#>*}joYG;DKeB0g zSz;?4PuBI}e$z=3nq5I9(eZ#Gq@C=pd@iMSwB8c?KLA5PyuJc*n*->poD(#<i`y=& zBytICE@vXN61O^buP+D8X<3|vKmZ?OFkcpl+LJ)EU#@ZXbP-c!B%BYGMh*5X9fd=M zS@`9N-7wVA1Dku-!NvWfu)b>;2D3fTm+gYiR2IsODlAruFjvjP;o=E+dEp?uv2+CH zDtVYKFCrihK!4^4382JXr2XQAngoW9F;!fB6nv9s(aF~nSXt!8l6q?}D>i|Sc^7!& zDh=-!-u=x~Xl=>}0?}BRVXRl5`4g^z=<_PRueM{#hr}~JPR5J>T+GD>H&5(sn;?$s z!esM!aQQ)au})HI0)VjUZG!`F!^SZf&gqKwfu;OI$BM<T9nKfet8dOZ@<Ew%p8n;~ zPc!Rt!yj0a8~ny-*QzL53)F%-JUIO<+_mq1I8r*%Ow<;0V9FOw$O5_mdO7RRy1^^? z?2NNU`I?l*OGK?KRH;w2TmTTHbYKSnKMS2}rxh=TE1w12q(=joUv|?Qv&|F$bfmM; zmF|FSDgzmng0xD3f)oVM+$+8wG@#O`L9t$iO1;XsfC-R9>=U+=bZM+ybIs$LCZOf} z;T_XF?we0O8+ba}GAwG2Pak0A=B!KkVDb@VF!^4Zo0s?)%~39$ZMT^g0igL+C<mBK zUEYdAaxQP_%AB(nyva}8Tk&mn;r;`_+U{=n)Q+ui?S}P`P9^ycEftQ<6pObXDHI?4 z;N<vuv0uB5E(kye0QlkIpZ9F--SAs$JBPm5o9&8US*|py@RdD3gdZLK1r+OKGY>=f zhv~-R6hO~<t`q;v&(tQUKt;NFc-{ch%_yM+*N(}VN!ZnC0do!5Ii<(ehQx=Y;JB0| z(gyW3;A{crJsC57^b#Jpt9<*6aE_CxXCUeh?pF$$+qrUY64SgwzoWGHHbnQ#mY)N1 zOWl;>ez^E+u?;d6s3*bR26Ml(F~HsvA0<X<^WV%N@qlPq3Pmyiyz<}xUaQvxpDVP) zxi;vUl=|jY1oTZ~a9g|*(v``;b>m}j$Hm*U4P=(8)%r}a^uO$$Tm0H}6Qk$7bq;VI z?i44{2iISbe{o^&KTlWY?rNa7kUCOXxOMzm*xI{63#+FI*gy&E8Vgn5#mE!?vJt1% zn~O+~q)hX0<;>PiUg;vG*P}xMiV{#lfa<Z0n?#121kACbX%sw}UumO{I25A<(n){p z?q|$1Gaf2Pt{L4Cgqe0fq+?tjX9??xK|DZhNnoCYt8~9;MtIT2w?X(3#@@H?xGM>e zH<P(}&$MTK0gO{Vm^ySunElyl84K7s<q4-01<aPNKJyXKefJ~X!A0Ak>kr-k0P{}U z)YFv_0+r^`t4JvYTLuQ;<J&fAVBQD<I94ow<E7*CKe$l99N+>1bO3;xMz5aQUzqvt z`-{^r<0UcN(GRz8`~a-V4mJ~1{9hvUum(;6!bz<F7gsu2B+)+|AQ8V_?YOmMHl4oF zuVo43YixayVDc5>apj=%Ny}5gV&R3`XWmdk6gg7{*M1-;@DT|+b||>M;&7Z2VBzs4 zc@(YJJ~#E(F!4)fHpMACW-U%hs7Jp7FklMMcm;_?Znw%Qh}xS-2*=*$d5&X!TS3(} zXE~A-AN}6>?>rY>reN;!m?ZtypPNhf5?vF&9cObhE6bt)guJZEb-}IMx4;nE4K4tH z155dr4lFKx{llBar<@F&M|42}Ism}F!t}$XdgTizDvNVC{q2KW;UgQagr0O)Ga=fL zI0koWac~k?TByhhGbmgv@h?ZFaL{cLu3ekuMlI#2Zik@3;R=n=g`fkY!8_N!ucAW% zio3=vew)%^eco@jm2eP*$4R?<U>m6)L?JYqqWy5)TUUEwe(a9b?whMF-%r(;Yw@Pu z5-4)zv4uwOt8%bmQ#Qz4$8qEpFyIrNH~8}CrUd{H#C_%ZNN+NyVAvD_yk5C<T&H7< zjZ4y4C-<zWu;9Ex-5}-R)@LH`nl_V50YE?=^3s#d!UreE;4Q0$wVZRM@?5#r_`-pu z!owDZ&r7=C0R4{1>+8?Xz45(#z4Q;|hPKZpe0=OZaMj4gkWpz5nTaPKC-7{7*xbb` zc{>-^%_|QWT$218f84P|oG@z9dS)&2R=o()qL!2enimN@?gcmv#9iZNUeia16STJa zLU4<OqxMAwEf>{^m#7cFw)04d0npvMv;>}?uD8XRIjS{@!HiREDKJS^T4avvR;l|_ zI>}>$lml_zQUJx*5FZNjg>R_qu}xI9WQ|j>Rip@~fN(&Mep%qeWpEvwG9>Xx$oe<~ zoyX%QDO9|i&7>4uxo!>Iyk(PCW4T^0<!iOCJ%8-@_dk8nmO5Nubin~S0Klg<{@V1e z`90r0R-S*l7S!XLo>6J|?M*kr#r+cyO}1n%`)H@Gw1^TYHU*CU=~)Eak?7Jz8D|}0 zfoKC{n_#x|A+kj1f^F&X18v79&?WK(c*GkQ1<%7}sef^hT=RQ&&Q$N*umqQN^;4>g zTvq_`djU<8(!xVjgj&`uC}Qz#lq^#T6eOimi9G8sfzoo6M<7eY1)vhpG_CSD`WM?4 zRtlJY2da5b#J9Sc9w3D#0d;9Dlk@0)u+QpEg(Yf_9}l5j_PrF!i;9o*HqAWowRp}p z({~IF!e=ht4jJ^`Q>_uyXG`U$UYwo#_9wP)nzk@;-qHmL=l}r6$_q~&E}r<xTxDrb zJ!r(UX{e(Y?%ezl81G&Urj{y!O^cQ+0O%8&YRCzQ$QC%Y4qc1X#<L(u@Zt=}V%1|L zT8IN5&PsEYm5y<}QZ<3eJH4*8N$)d`UZ+s%GVXiK3nbREnF-AMDUG3Yukm$-6bV^j zOB6&!>Hy%!m;rE2@Nz&)`IE>#ht22ZoHZ>dAsSnf65s=rKB<IHx{kc&5Z3~Czv*>h ze8tBL3D11&^j6wRf&Qq)ETJnhlA>UyjrI1zzrFNg80<{8Vr~RMFkdO}KAJCl<<}?2 zo)Q>8@9BaC^gAZ64_;c_`<>a!;@=nR<!LOOxAbm+&rIF`!=3%j1npV6&*JhS+2x7t zcU~7>PJ2H5*nkc|v(70vir{X7BM+KVSt;FAg5+wH<(#u95|^`SohQHcPq_pz&|ei6 zx@c1xTbX|Zpjg+Yt(>HE`6yuAeW!W3@&Yf~kVUGMq|k5*qe?Dm^+}*@pPSfHmH~<U zN(v<lVl<t$XB$sCzk%tm=B5CA&&{RG%^7BVte%FXj+Qo#A)cP$Tn=u(Xe(^$@6$Lb z)@swoOO?NW<;222G8J7gbio2T0KgrS*O#B0d*f@<rMY{njrt<KcJ;_5@Uab7Lsz=f z!;Q3DYR*<_`RPwE@il27xU3x?J|t_#0@(O@oR^zTGmZH6jB-+%r*$myr6MzdZ7X1o z=tB>gIFJaEHd%od9ZR5V0Xw#RQb%l^x9U}pfJ5<@Ssp0J`6wX7!=Tk{0|A=O<S{%5 zKIIT7i;rnsyx{h^e694Sl|D%Kz~`RWc*Tm6ZA_4CV_!s-_|V6-E0ckbY}yF#TDL|^ zuh#2}GsV(9JCB|ChfiO$r7U#hf}jf;&;bB$-T1zvFDy)b>2PWG=~_^)M(Jslf)A~` z0^YyoZID*24pXb(8VOpLpyTqK446yc5mn7BR_BXvt+eYywC)z#ii8L2JqW_8kmX<i z2cUGSNcaM~3jkf#a4W=&tA^uzz4}XVHh>VC^yNh?=$eNKkF5n6B4cih0oP}n61g1E z^W;&iE1aA0yrI53OI@t~W^2!N--Y??X>lt<o>=4#`F=gEQt-a9^>D++F>Sw)TBA`t zQYb$4;_Td)KE7@8ybiqLLl-=t0|4AKdiBn!{E<JOF3s(3py%m**>3pQ=+$uf(DoK; zQ{V<!PP?Xnp{LsGYLz?zm42V?<)z>RjV}mGR)=)m!jJT6ouwSTYt(ZB>^bGjLZU0v zS4pD)v<z@FlolV55(KdE%$$<XGihOb@wet){0U>CmFL%($qQ3o$d7x}Eg&Us93zj5 zsgJsVJUsV(%N+eB&&|2}%^b7O;^{Bv*Rri)g_4qMm#tY1AKo+pz1bxENFxY>nPTaU zy^Hz3`0(b9yNvE$fYb)`koFa39zIl@{j-H?@kErSK*5Ht5x8aa-LS29)Uzh~kj|y` z(ksc!aQq_R+T-0@ZUO2Ew4#;k+m;Q~1+ZYR+nz0h?oqHl)2DUwEi6Y>GMW-S-M-2Z zt<Y7@=UKI@Jm(d$)#Gr>vw1jDtS7;3mE%Dsb6iFBy5_2rGYcrudW5;^{Lb3Ni^sh* zo|j9&t}8dm8}r=bH*%~g$v%98!zw53kvXt+Z~$)FJOS&wyFnrAe6dnJaX4T6(}Roo zhwY7DIMfF8knWhgK6rKUz`eWkhd*Cw)Z$J2Gb#<23{1es$F70(xe-S#65yJPgV%v0 zZI-@m>}pdIoGu}1u_kP3F<7?ZYS*=PR58Pc{*sPgy*Mc>%WfEx@S)<i_#A%i3T;rO zLaSI8rmX{v$G8g~6}#KoVl~lbSr@(u6k2(!@Ym;r%%=mSoKI*t9+~?PeU3)HdzZ=9 zM;G|hG|DH<9|*@jN{cd%b={ZldmyYY_S<<z?IEsnJs$;f^Zu>x>4uv(Pr{C&0mz`B zE0sp0wr76v^RLe>eDBj2ZE5wH-+4=IKu2`@<OfQ-mkxb-=iHuqaC&Dd3-27c2yPj> z8iqQ0Ej9Shs|dz)w=UjZh6)*<7n*DfTH=qmrKzhLZ^jZA;e>_WBblUrNWvA@YZ0vM z%Qm<k4rp*XO|?Ng*H4#)LW}T<p1n;EK;-UMoTItxn;E<W*C{C(fiQ#$5;0;^#QfBx zW;MQf8K5w}AmEfmS~mJa)@fKzVD(J7KonSz;`!IdEx}CgzDsjK@(RkzgSj`m&67st zgmGOz*Hc<GE))!QcEU$DO~U1CS3xJ*ryT&`#n}`8IJL0!<y&`bE<u}OY6Ci<Pj0;S z_;mTi@9&zQdIhKVq;v4T)o+Cx*Ix<U>6}oS(?nxE81SUlmsayEiD!;;Vi%Z8&~er| zEi1U_X<T!oY72-MVC=hiZNf@Y8l);E{`oQzjPvc<K!Nb4-2&T~xq0Nt2Ii<frfvG& zyjKJ@(N*eFoT71~5zA~!naPX%vL0<4<qJRn99tc_f@QwI1)!I80J)X$T#kMdQLF;x z&}o>y1ps<LA&$uXkEaP;hmQWR7I(r+e9y#9Y0NT-^3|L(-I)x0Xkr}RGrA7CGa112 z;_TcjGlkM0+_G)*xSi1pkJ^CF(2X0eJTg~Z`tY8m!zXZhf3^p1T=!0R|Jt`gHWg`% zoUq4>HQ5WB-|jUCk96RccWLKbT^w;5H(6BlyI9UmOZPu_l8@qn`HP71iO0j?ey84q zD2*+H$5r2vU5<EXYhNMO6(dh2J~&sY&$w~rI0Zu{b5j;Be~?@@E3ojyU31J+V#U&r zHu;7bz6}qEbnXK8#4=Y#Tefut%v_}HP~g<-OY~A(IflgTV;LS%{pJgI5ib;Q8QCD! zAK=Ioj<pjthx(UIg>SS^j6q*VRx7b*Ve$BUrE=p9lVe9L%v`Y426TarmFIWQROW9u zQaT=g*QfwsRcAl^#^`(C%HfN_jDf8STh6VijB^U&y5?@eIt3dpJ-Q|>Kw{0>7ApJ6 z8sA^JJ?@%KST`)!2ygh)G<L%dOL@@u07%B)X5lbnph8|WRN}lAm=BjVrNBO}K_Un> zK;-L`UF?`goQ?%F%BERTcBRQqsBVQ*sbXcDSJWd#$Dsv4WB}Qv7P0jiZ?e0TV9o<4 zDJ~4iMt!!rz?pk$t)Jv~)~)m_nwN}*L#6Xdzorzx6>C?+O`9iRIM=CNJz6N1XN%<< zjulILpiL~b0bQV5#;yr=FCBSqUw-Dc`AS~ftYEZj1a2LFAG~E?6Hr%rLIF7oAP9j< zh35)g)0c#&i_$1V(=7S1b&eyCIopxWT|g*}k*pB0<!o=VTQ;}Q6(gFCi3+$DK_PBJ z7J7Q${N|6rLp%<+>SX*lZx9W-V$_K%Gz?q>I)+upc@3nxNjnV57CNnu+$%QP83k6s zvW}AilHyoLn4FJT_+wEYwek_ITdwYiY~o$=Mn%7gVx#lG^&#>uaAl;n6uK=czIy5K z5PV|WCRpFot<|tlsgw^c6+X3hVd?pswoLfA3NJ`%1G<GiJ@ISReTAbx*_}W9?~3(u z0bkqRHwvE^e=ltAT_10Bz;8tvKq6ojN@;4YiCBxSQK5(HqGS_%NlSW?(vLB)Qx`m2 zAFh|4yZGeNDIieZO@V9tvVupiFCgizkuwzvo6-~r-JtwS<0T1A3FsBd#wiMP9^oGQ zC@ZKx-rqAz#3`plF$ge!pyy$U8K2lo;ZTHZN(Y)pN-N{wi}hkjUJpI3`MkUpd_r}J zpTX&}2lK3dYc7pBCkJfvCcJxwcS0z`>@kp13N{V&!7W=i!Ipu3jjLj<R@gJY^uO&} zSi1ic+c#CAO(L}c-9ew+c<ti;!pz-oEFJ!Gxlz?X{hh-*;Fi&=VO?$*5?3K_`9xND z0)-6#z(GHP_}mb#R=_sfO0F@Bojw!i0MTl#^9$PKhvSn98t$4TY!GkwSbXDNZ(EVS zC{>0c!$c*#<GX1q$|(VyazOLj04>a?c>}PrqT(a7ZOJl@=0TWGV=qO7HRhA!UE*Ky zS>vl%97%Q2I~iq_taENWnZ`92yN|*mfjT#TIqv{2hV#2($8!o2mtQ|OW18Fgh!h+# z4|C2c7#v^tI0Z_jU|n}N+_Y%|-mzwtR=QGe6!y$7efhvr{+qXKn_Pl6S*Z=^9(42A z)kh8$Xa9C8fAsqm5<~q1Yu*kY-S940-8n$OShtcQ;O5@iH6wXZ%g`p+lhzEO=c5N; zvVNKt)f=Ec4wR*G7))>;`i#v%_ys;i!HH`_#T?=>PEw_|B>{=Y00};0OgUa$vCVDi zz*vH^Vh|~q3Q`2vEy{!fh~2o9jevr!O>iqFpYI&D)rEhhwrQGeKH?-iJ81tbo-)g0 z9-a>qWRp1R^xjy;PJH{Go`*d$)(Yj1l(Q-*i5ydrA{5Yi1cfK=Ua}5X<vQU*ljCsh z*m|u<rQRs*U0C|w;e6q5KeBn_1;4GU548c^lYV{u<*&_@=01P0F#A}gQH|X`DV2ho zHe3ZC9lZ*MJE90cx;2-;b~DXfTKKzQm-`wMU2McMwPF>r%%vFTMj@_EAjdZMA+CcH z&@F&j%&+7Imr_036Kf&;w|YzIJ#~$Z1LPI1Qx^8-V;fHKlG;}2a-=kIUX&L2j+#c+ zKVB8~edH}|8_p{ZTrK<skgNgmk&Og`Ab_3^&`NxAZIa`dSDOdTJmw?AQ3{eaM8Z;x zYg6Dw0U596?@+E2Zk!y48z;xLJ=!bvM)gp>@aRmj^w-x-jJ{@Js7;94fZhV_DIEFb ziR$8C94jw8Q*G4ZSFtlH4YzE#8a_JuF6hs8F%VAwkBD=pw+b?xz+<#=-#6L4+oQ*= zlmjr807qSP_czfU$k!uzM`Ypz7EwajrX0f3t39D?1VEl-hJNL9=}jqeizS5-^Co#{ zP<j-Cm{eiLl()?jWnN;31Fr$OKK&aLrhd&6BP&o=3tnKD-=EzA<k9`N^1;t<WdJGW z+2oC{PfyppK8AJ9lnKnV{*El%I5`d<-8=!AR02iSMx!xXDm`<eRQ`*7i%Y+RHhELp zouy3?-TTF_!!>u_w0|($JCjbOF78NW)}&Q)Kf<(1!S=o}Xao&-J%0$Qjk-}@(4B!_ zXg-2FDjSevrhKF!$Fey*VBZY(;oJpKwzAxH+qG8H5`~K2M7LF?i3%)b0duLGE04{} zkt`jlgkp}RHmG3c0L;^}xAv9Z0UAAx`{f>~kmMLBD4#MIMF7Ol2?j`wWAJc!^J$S@ zW9O5Cp)^M%C4d8St_|Fu6f?JEkXBmVjxx-f@;%uOxM|A-d~EXsbf8_}YK=x?zFc|k zc&Yq<zc4%hz^5<TLcd{clZD!V-Xh)m#jiK6x$~x}zD)PAOe%A6M>?}Q6@q$3rD1#D z7z6<Ddj1g98g)ZlC!&M{a+h%TA*BO1fT=;pr@n1TKp+TQ_S_S&Y&>{B65xbpt7FTR zk${}?V5^I!x$3}e+W3!VmQS5hT{cj2-CM`K38#vEk9LU<1?JfEE6Z;_(m7(w%bbhv zm$*Qed-0CzgUqu%pPp_9bDlr5E}i!T$fYtQjhVaM*(}_=c@jRhWkTE1wblrN`AYT0 zW5x1++;!~4zkKSV&FweZTckFiFN5y+;(xEb=gymV_hfUk9jVNlJ5t%<R2T**lS;$p z-VLAvfY+A}K{cp5AcR}6uKW%G&B_F_h?S7;Y`c{go!kKABrH7Gm*8lfdaCYf_u*6e z1){(B0$Qu-5^r*Tdng~z_6<wd6hQyb001BWNkl<Zb&q{ODC92w6wD1mTzS5XiywEL zCb&B4(kx{T^tifGS{`$TI{F&WYaFjB?ONgmuz@a0X8~G2Hn($?c(SK;WioK{mPxpI z^8|FEEnVwD5G+<IuN}=7Klj4%x$pgEdyn>IQ5(>gN#FhAKh&<d^QPV1>CV|)DtlQ+ zDmxg3_UlMxV4`~sD5c=F#Y0dJu>0M%7$Wj<XOjgZS>*~G76m@Hy}fL^?&5Db*SUPA zVB)<UW-k4ist-t6cojjNYh6-8eEM&zKT3_>X6F<Pk9%VPhR?B^FD&@&pV3LYq4Bf2 zw<W%qJjm6~gSkZ!@Zy1=0};TQZE`@1Jay~~fAalkzHu(e7fx9a0G{DZ0WdECT6ojO ztEtp<rqgiK<_Y-l<VI~v*G3S)Vx_wGNWS<VcFmr+_cwQJ);<qzlRvcq{UqqSU;Kya zwZD7I8`)H5wkOkhWk)*O8!f2LbQZ?CRskpluP+^fdcavd%LT(I4+RZH*I|n<yt(*j zQOOYVw89h4Z!fFJKe-OB4f;#U8+t%A?%c6207--dy2AByN=u6_Y^wN)JV|5blcv|@ z59k(PP&5yBPR9wY5pBa5-?~66EAwg}e{(K!zxcY(+%@yq6$a9V_}Qmfw+`lf+cKCp zk2_Ln_~_;dxN*})7(`pT{{QWLd9)ozdFQXX`|kI?`}R#wZ<C%RV;eAAaBv7=F<`u4 zLok?}NhZljLT1TKl9LR{$#D)dBy%`9!2B^YBy+M5vzZthldy(>v5~xDFkXZ#OHb>2 zdV2fam+r3l<KDivy1J^muPoV;UB6@bbyrt?_4RV=_kC4gRZ#$?roD2aP`>@p=Js8` zym!6~jdO-3^yi7YKJ^ccU-}QX9Hx}6_r<brjvH12X#EUQRsvJ$VGv^ANXhfmRgHPn zKr_JCczKPqN8s#Vh<>;-dEVcsq#J<<rDY_M_&(i5GQBj~J|eypQR6A^b{934iUv+f zgx<Y~=G4m?O;Ngv9D)Sl_s;o$5?uq;cRn15p8>B2|5rp7!Q|kANirf+)h#1n3F&!( zUhVq*geQCN0+~cruk1ax&q7u(^qo`Es>?V05tPZ6A?@Faf2-B7XC;y;e<s9tUDQsn zy$V733A07!@1EU>p=8qcILpmu;km8CpB~vReCd6A=Jdib&l6EvZH)-H>*W2JiR9qF zzp8)XlPRm)pF}~iUN7M5%a7ozrw^d&)FE#40soJMpEkwkVaeQOjwxe(!=EOENOn|+ z^pxd`2v*O4-l7InRD&#^?74akDqn=T?wbY0W|Dd4BJ^-wFwG~Jo9}LyJuB}0cD@N& z9U^(E_yy*hWX8)`-MmF^q6Jbi&peWGAu~qWrX1xLb&}L4x*jR8ET{(w{N8x-6Up;_ zyHV<8jfP<TQsW_VH#_sh1X1e3G66jZQkIDu=4SA&*_{|n#6cJ~uiAFwiPg<NI8(0t z{ml!r+A}{7(1d;-ao5TFlLPVGe|po<<)28H-7z8xitR=j|Ge}t?pfN8id|Pok&&c~ zI9Xz6NW5q84Sz3V&S5<O5%lpbH%t7tD=p77pdA7c=_S)oLHO*nK4If3GQwmCyT%#~ z@-gGymU89Zrzl%swK<V|aCIp1Fvg>w$VDV0Gh*3yFT1}8h6O|9-78Uz7cln{)d*=H zQEzQ_me@u2p}41jAtNT~uI(Pt=!it-jQma+kq)9`>Z>Cii{ZxkSzI?Wg}y}Gm%HIO zcyM|354Y-#|NY+GGdck7JV6usdB)wRerRUR)StY0<jRk+qz(WjyN0ixK7e~p??>6L zB3eVw9&^O4f|QUvd0^y=>WhLX`FP_%QBG=<_#4EaxxsF^$<`32pNa^1qk=EftI-pt z2lIXf@>q{o?v+QZJJ3jn8Ds`pTiSZj)LecV)YY$p=)FrwuJcG$<QrmOaJ^DQYCy>3 zd-bz&!i<_$9{=2IRqqWa%lECx*82()dSrqQ^wfF!$(JMU61u7ke-EwvnV5x}=4WvI z{0uToG&|5D^B<mG`LnX^{N;_irh^N1Xq+=Np<e*pb85etk7a)Ujf0ncob7%GfSS|5 zS5EE6y-NpBXodxIvad(bh^lr-Q+8dmvZHjFN71i`>%37SIv2_cl6vb{MXGGhpqx&c z=N+?p3wsHodiy~w#bD~@h}OSYFnnp@^$YG(IqVXa9`df+UU@L$K1`M%Z=|kvQ6BHT zwZ5m|!Y8sWY0g*{E|{Xwx06mJ-QSY>0z??z6VmDdV1F(|P?j%G1n*wn^Wcrk%i9dm zH`UdnFCNGB^E0?<eg;X?AEs5c?dBtA);?NjG(WA${QN@)#a#g0`N_YdH~!v-A1~R} z)q!~KnwViGyhhG4OziEO0sx$>tfJ;bT|0sO5yAi4>a<scO90bA$r^l7S`?z@4FV$g z7ji3X;9lpS*!t%^Qt@hNtZ-SyY-7qCcl3ay%R9_y5Y-*wS@^Dt^Rkib>WFE{aS!9M zV%=262m!lGn!Kw$0-=WvvqU3v(HA2A%UvhzIs5yNJ!g-^4dxAr>Xg+lx*tPv4O~3} z<3MyQ90ON;cLaj9-v#+Nxda4*$t13yo5p+R{fov>v;yFsT-*BN^;-R}Z`wVh7mc|9 z(1d=0@a0eay?xz({?OBo>#St0<m+QbEb9e?Sj5D>+!R27)0I_Je55WTU+z>i{m3IF zBD3_PG?G#Bi@FjG_*-NZiE;Hwm!Fk4fa2)(sC7zo6dFGMT7>#5y)gkg(abE7$aR;` zHJ6oR?t`-DGX2H1%J0ozPE4VyZ-cK}WLT+w1Co1YrecZ7HAGgxAeQ|exW9x5ev&Hk zmg%7W&3fbUt$NsJtCATm*E{y+vCD%jWqJ}2LNJ_4;)c0t+_-Djx16g>DN0Ry<?vSF zPfwT1|9JDlY!w<81e(w<Ain&mzi+<nKfeEvNz9d$8GlvGu=3uDawajbH#Y@?7+9)p zpzKryL$<O;)k`MbzieX|LJ(qz8k{H|JQ4hhSbyjCdLf!l^TReL;dKRMG9*G(&rH@Z zMr}O3F-IcEE`L@cuRPj3ZkC`#bqVwd$Y8JY@0<ieBGhx?RXTdI2=l3heG7u?-t;sA zbXTR5<!5E`WbR#)ed98S7OM&SM!bMK(Ki*WoAsFecc>^QT>%aN*Q?U{8H#!}_&Pk< z-SP%8Fp*B<hPfGBKj+_QrL_WF^Tdfl`SzpRg)iQ+XHG}6UqEO=zrbkCQ-9y#gc)Cn z8`kA9!y5F~emB~rp0ScxscmAb;eG3(#zo>Gc1S#I?2m`6@d)d3mo+4+03ZQaZ>Y0Y zWpw?!jT%c-VS4k#)UI2pv+Oyk>QoUBuXivH?~!-^vdf4n$UQ*h?7gd=vFuym%5h{K zet)8L;{RlP2QnQc=Pfqks805b1kXM29fZ}()Z)bsct6F?I|}P1lYIjOK|P|(p%;<4 zOn+7`>Aq#^U#7P8mpA_WbrTqv%ja<Ot~p#gvje8l&1<`@<y@D`mH+<i=Jr47dFB@$ zn$TYW-1Vt{X#B!QZh9_jrB*Cr?u{ANh__1{Aq2a!6BteOW39f8v-NER$kFp+c(fa` zU~pU*v8ft!Rbv*#2#7%DLK(bqAeIxP@UVJiB<3~Zva(U`TSXY6KnIyju^vG$T_jtk zzv>>s?w8FcFnAcUh!&*BzXRgGB#rS<oiiFxQ5<`ecg5=vR?hz({a$kvq6OEhCelaz zdm@26vijijo`d=Q_tQxUc=M8bXL?cyF>v|N0B+s03vZen^UX20UDw@iG@n^1S3myr z`qtfg1-KUmn$TY$eC5-hZT`YX-uqnEO05_MSzxzb1%Mr?A<SgPP_U~wQ`>+`x$)>u zTTZ&?(ncr>_#b(cU^r1-J$UB)7^Tqo5EC@hjCTG->uL|m>gYmLB<rtLrJJ}e$$k08 z&($O=5B3ur3j@lclcN7vQ5Q26tha7<m3}fgDt$bHk%iu=>J*S{pp5DsyzfsXTOc!( z%>DAahJ!?&jC6@8zqnkN%w_sBWteZwGEBU2d=$6sTfh}V1HPQi_7<pX)!JXQH(Jqa zv%f&lg#H5JE1&)c`%NFY@krK6opwRzl4fkoB;Dwdp+p~cXD895HcnO6(ClpLB5DYt zl9>pq29!M){gai8pby*72)*N=tYEFZ+;<2$$(2;3%bt^}JQ3JS>^=HDaWPqjyfdNN zYJ(wIP({#wedYNgqy?s2$;yP0GU0OZx{A)h8J1DV++Q~VOR_4$WUh&3pa|<@?uLoj z5C6{idxPL__qdZw_$;{l;M$#(6~o(hPU6-*yD*c>`bsn$x4B-cJ+@J+fBdPn&9CcS z(_UC;LVtmA_oqK=|NQUV@LbA_AF*9$Dq|&fn8fU?ywDd*V?Hwh%P?`Ox`vwF?2=#S zH^=?(q~m|81`!Z;rv{EyQ+IqysUcjYDhk1huB!5eG@R^$A(2Q^c1_f1hCO>ZS;;+K znO@$z;pz++4Jw(UcP&YyY^vxzhCNS@97NY-`Q_I=vJ3w%xaS@kfT_Mtgv1>79m&XE zCWjz6hhFs?<?l`Yow0=8&2KP&Ro^K=e<FeF=Voxz{47S(DWBwq<JOkSl^?8CYae@h zefzt5Kl2wJn$TYa-1F&wbbsL^?>%M`<CzAv2XnF1yhXap%B8FXW;0{R#Zov`T|>!c zW_kDmcs!^YeD63)!@!qUoy*c>P&KyQ>;4p`AypD}RGmD+<Da3z00@;E)tFJ2QBO&e z8A3$j`4foeGplqEJcG`#gufE`v?h`Mgz0Jyt6%h&z0NEE6UZgIA4xrgI~U3brbWN^ zHl%ABsOll@|H8^L$B|}=w0~pD9txTM1QVGwZrL@5w@*(YA6UxOtsF0uzPeJW{*R;E z#RosMZ<i~$NsSAPURq?03xIDgKejNL8v5N`*@@punTa%et>V=1@cJR#ed+)XmzL0) z>cYG-<>n<($He)vB3YumJS2JfhQ_zh4O=EyUfx)TK}H7P>JBR-lO0x;Nt3P|)@rcX z<y^hAXz!1e?-gMiW!1Zj;!SgTsEA;q$YDU)XQv{o5V-+DSCMkqHyQTKTJIyc+Hw>F z1cDw3xvrj9-m=*vl6jBQ?SgB|v(H=*OxON?clYOU)BFrxH#UMax0GwuwkwO<rN3S- zSN`wYXLcNh#)}3`=obOLcKX5bsnqao^O=di$j37Y_FCO-;+et;eD&0Wcx>Y^94az= zWn|2rvxw5z_euz0dJhEW%JF}X)Wla+sgZRJPV(m<TNo$mG(NVz_Hke-QJDl8DX8jV zbff$=nL)!h-l}^GKC|!@`4q$)xvO0!%M+<uG)6*riVbhna=P~+-ee_6n4LU5t<Kjr zOO)?XP>-_bCs<Fg8{dOy?fBOFH;IAQj*j4l`5EjT$op1*1Ay&Dqkeq5^wE>0@)xe3 zpI#9N(s%)(3H>6$Kb^QgH<KBA`_A;p7srzWK2o=-gQe;^?mhhwzQ6KQRGhHg+JImK z&R&z1>xH~Rz)zzSda8VVU1INgUSYaN)G5OH@X_m&jWsjpAtc_-8HL~^??&qVM>WJ` zMj3p!6J1CCSY%AeWJw5%F$n#45cWL~|2G&)up(W$--3KcGw+=HjsoN?tCuD7V7e@S zOTDnXZQVP0Sv^I^ZDMaHr%VfPnVQ6V=4LRFPQx<%^{iAX^;4zF2TvBt-@SQZR?jiN z2%ri5BEpxB{~$J-8GH3;BLD5V?6_|(2n9v4S;aS(AH%(;AHqhX1bNr5%sY?bb@Qag zAIr#?gK(n@nJiY*F!{ZbuFON`<#1&}NnVhLUHenmpaX38dN(D?JqfM_$X8^*snQf+ zrl<Mqmwf{gxx#MtC<aTAxI|xzTo;iZY}s&wfbCogP92lIGotw3<ob*EPZ!Ac5NcpB z&n$GFf6x#aOeXN2xoKQGy%V{Z<(p#;0E>m<#(K4O?eRkSr|;i0r-R=v5@<rd$Z*f8 z{bVGOpYM-lzJ7Urb}xV3p)L-r9mGE#`!}4dtTI=8EjyPMMiNoR-6f5rY%5n~SEsxl z-Vb90Lfi<k-MS=rJ8X8!mt)VtW#-Qn`GxhWe_HDG*%i73?kTKcXA6eZ#gR%^N7;6s zA$5As!M6n|JG7x9`1Vm}T$zGh4Nj~__&rI9tfP~`>@zNsEi(3kgecZ8SpW0$%vtb3 zkX-{^+?6lTy)Anxo56?oE#Qsgqc8*uT0OJAb!fZMxNfalTfA}COz2>i#tR2c=ocxz zvGnNpShD}qSLA2k7dN;l6aYs`%lOQ5-@w7bN!ZjyG_RTk&v>E@H2A!V&&Aip4oRcq z$r4ed%peh+^MoKF2obRd%7qcCC|&VPLp*c&Ze%LRNS$w(RYL(GbqOQUfoKMYm>AS~ zWqSLGt7Ws$_Ohg+=PtTmp8Qm0g6Yw`<)E%X9c1_B)g#iMmBFTy5YIm-hjjE3kvV(b zvS2L3z}|s={O0ACVLqP=)YNcY`|0(~yH+c;|MJe+DLr0(5keFCMT~zs@xb7GcKo;J zGZTN<7fTHo#6O6&*(l*}kA4Rat{+6%_Qus^-R&|&{RCtr2!BJP41)7_*AlJ)Yh8_C zJP3&jj9bMJx)P$sp1&Seo~ekP<IXLQ8r;)d)MyLP>Bev07nMDqu;;C+C-}VhcN1FH zN918cGb-bvOR7}4r@2ICq(DqjS$~>%Uvq`tkqigF4$p5-bD1H)5P4whWcmGMEDJw3 zK89btY%lr~ai7+1YlD@|#X|9~julFuxq0{OCNwTeXhOfp@%dxlPwvU>xOqov==PCh z-Zx(zXa&rD<>Y>Refd$W)wkPA#`f}Bd148RewIMmkg|0I$-H+G_x>6HT!_1HJJkqe zL`hTWF40FCpv0EwUZdQ(wBAn72XiU38(GyWBT1uO9lN~;vU_G_aYQR5LXi%VYtlL9 zGP2|A_nsF|W+ENB=l&^UVS0M$M9>Q)E60&;$6x`ZQReL5(5ZIJ)9PW$n_&P$i4@*7 zyA$u-H3y69Vz*tlxmv9qT`pH|e{QRA@2z^}w~HE@&@TbpvG{LfXL|T8vzf8~Hjx^- zI%b$To(z7nbrhdJb|0QAEu$)og6A9KD5R~pE(&@hZV1@~>+EXMi%z@|!kh~O#iDdY zi?veg#9R+F=zLC5Biy520iuaY+$#OMRYu#MHDs7VIOGsfM<)2qUrP^$L1^SRPk_u9 zNJaTWj+OVz--$=&3jIZ8glkRkhBx=LgkA0azbVVauD(2O-Lo6793J#(K>;)!r+B7P zeeig({69|@%lCa~-!45~evv~H`Xz*~oqFhsEAlhHJCf|bC1u8ao4WwOM!kqTPd<Q$ z*AHQ(w#9Vwsz_Bf-WLI((c^5IIA<8)`(=h181QqYPzPC;Z7=nSNKA3vcO?pGa_|v= z*O<#|@E^+z1V5Rdn{LdxlnnVaxeU*1?FPTGy35`PtAk2k`MZ?Q&km6hsRzJ+tPX;c z91HaezGp%WW`u^l?tL#^(|I(V#v8^)am(&`3?_WDWZ_autG0c1wOYITnf0yz^Pc(X zrvx{taS=ij`Xz=hAHRR>l>>9XHWcss&Hi|1&LaMm9vW^F_n&<l-#+s=o-Lk6-DPK# zh+a2u<)34ByRy94-wJj+pG&U+SEta2kd=ubPo+ns@#5}1Mhk?Kd7QlbDCI+pBg$Wi z;+0C|QrR;ICvpISKr~KQp)B^j6aQ-!8aBc2R2~4Q(wQjg;q$BRQ<k3_J`mN<mG6?c zT8Fr4Vj-W$+oz{+&BQq3+(I$7OP%dTeQ~2!|9?-eZGQHB3v)X7?Gl0}^h*$TEPgMs zuW#r3CsG5yF`VeTI$^|;>~)(uI8s{1x0Zi|M>Y;)y<Tizk$LAHd@Uj(eICN-Xc4LT z<%f?UizNj0BtexUdy7%(l0ZoW{FNR(KVKca^q@rXNZZ$>p1G_ZnfIuw&yyvJ%OIRB z#O^F6GPXjVw{Ru5uyV3)cGdf04aW%iyt|6zne)b}%E00bg-(9CF*TG-;<ckAxORFc z=JS0px$*M4<J8t`^#{+CD}Vd!X5p?6?c1eV!Aj#IgeLS$7~fcW^y(|}Gq+}}<gX6I zbNzm*rdY2R@xbcS`2N|S;z;R?WZ75`5y{*a(asf7lw*A=f37H>AWt9!(W2SUH<=6c z2+6A^DMg)uZg!FPC6d#dG1A+(Ij>J!mU4Mpnb#Q9C0M(P(D?FE-!<cvcV3H3KZ(q9 z=r#`@Hy5N!yV|*5PavN^zexz@`|^16jtRVJavX!nq%Q{ruvM#Xm2La8&#Z6W`Oev$ z4?^RTgeLS$9A7$q|LCg+=59(F@&CFrJ#rbp5JbhP<C*Of`0mP2@S~0AP_+3V)gC{A z&<J)hf|S-vy&}Tv(GXCk^-xB*@|mcFs9}!~#HI|)dOksL?ec=fW7Orm^auuCK!!+X zF=>Spd073TdcEVIyl~H4MdmX7<o7Bcr|0sYb2mFbq|iFf#$vc?WEgLqn!;s+{YY_3 zTDX+rRH=NhX1kwya&7(I_wSiM3yn(_n$TYYxMT5q=Far+TXv>L{@rLI|0~&8$`>`| zP#4S94Lr1d2>-V71Wr^|+ul0c5JZXUhM*fzO>SZ;;~PO$NkKXV{A<LAm5=(FE67qf zMywt)_sdXpBl9Aa#2O}3kx%KFOLXI}N9vJ@NO+N!bQQ>qG~6N16MfMbK8^nl6nWb9 zbZ5|=3z^IHB0gP2@7jP#2zKVO_@x~?@cOY)jAzn;F7{Hh>8w@jpF347-Ep#1zVEhu zyPZH~8kZC_p}&OiwNnqzz9PT#`h*d?eJVXX%wI3rH5@H1<2z@5f(O@s#w|t@@l)_k zQ=`f;R5iuRt|`X#ed}=&uI_NJIT}$at_AKj_}s#~u-SCljY06$5rs5l&q+|$Gk}DI z9%jU`q#^2Bml*-9T#k&n4OfC?`ML#$KwzH$m7K1uXk+FA8KDcu_>Y6Dz=`sUjFd24 z+Cv6``|sw<STX$E#2DT-HHEppK4fBng(h*jR9S1d_U#8Zw!iV7x#?qp3>udtG@-x5 z@U5jEWk!<uYx1%5AMZ?$yd`c}zIW_W7we4@e!O`EUpaXIC#$P)rCu(FknVPtR{31A zGrt^J9`5{{#>`a_;vrqxfyOy1k%ti_mqltEMKMHVB-GN4wwbKAsBT71=M^ao2kEo+ zkGV%P{rGn!3KolEOmvNkU|^c8EO#xkk=1_Qoq8m}fIit#?%jVJjFfNPr$G!%WwW?x zeh#l58OC5D5m<}8;W+eEsr>yyqxp&TTJ3?iPft|@3TRxS(1iXH#5a~6wX#-f*GMA& zYa@xi-y2HwrT9E`w~3Y77QTAwVSH!haoDcw_k2W~t^~XkF`0|$S>{=?xnz;hoF^L~ z78${W1)_<FM{r#-UN7EYg)J{GC4_WrR%M9D<O(R$TL}%asdN1El+1M(l6nXsf&$d& zd{g1w-XTGF(t5-?i0ca}AMoTw#4MK~pPtqwVDYl7fN0Se0&qPOtV{!zLGbpeDO^84 zi_ugnux~j4Y}9Ji)oSh2Yt`CkOHKR8yJmOVflL~gG&G^VL~-Zw2guI!aE1VH9ZUBA z`BZxNs+i&LdZPfUP90BgpTK91d<&;5>wY1DWi$bSI|;AB;R!wZwxGORCa-W>oTyyX z^eERD146oX`gtUDpXaDDPyjiR3i47uHH>(p>KcW}y|kcr?l%KP^$EJ_+vUae%DiCa zOAI_?k*<RC(0SwCzkXX-Mfi-7Bay|I>kxV%55Z(6gWtUT6?nzq0Fss!kkE8poGz7r ze6~{ka{%8vSt^&`zc3%QUryr^f+qBrIKH*?Bctg$6BDVyKbXso{?=eTm*MkJP?YUD zK7Z^7_?P8J&~zOMnR^fuHJht@Rn^doN(mZJVGvxeM6Rkw0AKX5SZ=f}P<aDLK(?J~ zf<zQNXXPmFRZ8X(!%0Sx9j{PyZ=!ON>ygIG1;&bUyquTE${>=?rU-;C4K|b46O<(@ zuevX}(MAMg_%Xx4bu%;g;NCq*nPy<masb$@*GtC>#lKlDS3emujOBOCOsVFsYFy&b zg#I$Zznp&bx-0V2ADc)GzDl$ut4m!RE-mA;i{Hafw~oP~E~v2U(K{nj$C>esB4{Qc z8{RYbSB>ybHwtM;$|%Q*+1%Z0@(oQ`U3jB}uP5p~NpxdKB4}*L?uR!P1bQf^2u2`U zUof6b7lj;U^tZe>BXV>(TTj5aidJ5}6)Jb`>-pjH60QX4-d&r}2>_E2Tro6+5AWNH z-TAz5&+>-j*k{VspFF*>dHZ#9)87bW(0EBg6Z*>xpFeir;I7R0pS>bK{eiTV7&D0x z7;LLJb^LJkAnrZ=Fiw@%(Qs|3)`jPJw+j_<@}_`@oZ#mgp`0l7iRzU!_Cf=KC8X|F zsQztG!@NF0mPlRgz2phj87=BwMsTwHyiV+SuqS~~BGH;HFCgf1T9&nYtPX-x+?O(< zoiSA<!D({iM0H>OvOJj+5X4OrJ2F|^FgJ^<C&mMF$^pQo)G0UZm7i^F-nm#Pe(cu0 zySL;ws_{~TCiIsnzIyVZYhN=k|Iy)O-)oa*Jg|Ek0Ibxu@QtM(VgK4eoULu6;o1oM zWSHhoa)nP5NnjxC&Q!@&5uyUZpgZrR+sKOLs^SFN*ICa@*o7TNoMB_<9$9#2q<u<3 zq+8;KoD1Uz*tBqCAxP#j-9>c+;_mh^G8gTmt|;dbc<6hP84W7(7uD6(vjzF~sf4zO zd?cB|)e{qVavyx`000<7Nkl<Z=k!jDrqhAk6hO_ki|e)8V?RE-{+BoIn*CRSP>q*3 zG@-wYamV8K)3ce;+pij!dyh%Xy-713F!^oj;!xofzPbE3p4>W)^?C_5?XExJ`R9IL zJ?dx0HEx{&Pa^TiMP>Qpu)JJ4J3jB}Ai0m|UF>YVoX6=S4OLgW>RGBhYW7OhUD*WZ z(qV@vdUuK3FIh#7GS58BKx3p+Z;$aXZ&`5f$`}T=oQTMS#$Py@i|&Uphbe(&5DX?$ zxMFY!*G^Ak&p>}*aToxo*^cc{_s|oo>;H1RSpL{;`*!Q8XfIP}Lf61uC-%SL%KXgl zPoxLmkT7Di{M>Z_DBCqWvi=-?aP}!2DxSu6vjR#f7%G%_uq;&Gtct`#$|*f$Svup< zvLYm9&W+4F1-jmOWc|E!3gvdGf>{8)ce68TJ?SV&V|qHe-g!i?+$-<PqYB>h%jpKe zMexe`^T^}oETID`@7gb4Wz2X-ZP|n%ACF^ieh}B}n8fQwN0AnEuQy$n)*WYYxm14S zsrAiI-m)<Ns6ZKwmk~6fYXAW5KKY>47fXHc^8EBIDKl|R)=G|;B-mK3)V8pH?Pqv= z;|LBHmr-a|p!OzN$jF%aD<xLZ*!Q{A>4_sj(Sp3}n7P;F%Da#yIz{q!!*o^=ktnxH zCjSiE$I|ZOu<m|;x_I7qRBsuP$WLYv_#@7vlC4UngnUEC_t|e+Z5*&=`(kk{^!MYc zkrBLcd;+7Xz!DO0C`Gy1JX^J$A0FJ;yt~k7+<DWkIX$ObLle427k4avpA5zO#>SHQ zUzyH~ydz=6-js`_0@K_8;6!B&kFFoak2e=_uy7I;yMf*amSfY<Nb0D>7bTsoGr;P; z^8RRXfdQhbR}?bPvj@tj$?FL2yB<cyysRD!iI6nWG^^0Ek*21x=c1`;QH%j7NLGHV zUMxm(92(8uI?h-z>>U`utA|JM+R;($%w{1%vDqv)9B2Q@V(B|)tJOQ!tM%2}_AP`C zP-(n8pb1?gfG-}qKQ^B1zkD(^_`bnJ?z)VXd}T^7z77D#N@ww-%_I2n<|3ZiK8dQ+ z2$3#ntV2C>pu2)rh^)x<f@yGhxn1wIxAoasaiZP@HZ4p}g!>alvPUc{BvTQhj>Wf* z#p|WB#{xqpblhA{=%Vz{vH=}cb;|B5#Pb$*<NME3mW9g(265H!2wpurjG4YZfgV83 zw(YWQKe17(e{;E9xof3TdFBIqb~lBYHD0#RgsvgQT_+Co&16PiKNQcsw=b5yF&|6s zv<x%w&A8OXV)-n7x^*0nt{=w1!YR}owyhC-W}<0nT@DqOk;-EWhLHi|(oq#r@!ok4 zI!OslB_m=!j(DHfv@}5RyuD{Ci;!>UVcg^B>%^<P<uGH$-{TPU%p*LHNNd3dk9*qF zJY?zDglXWifkC`(bPQJv4PiFdC!9}iyDlv>8Yc^l=GQiAwXdEimL9!%_k1CEQyLnY z&^039>!%-^oXd>8Az@k{7>H-zosXsa4Z-+&!?kg|yo#r{PvF4XAsi|!wWqrAXgAD} z7A)b)_^$D3VO}pgrWqDUcP?bvhR`#MYH$e7eQWFkd~b$&@fbyY!ZGs*`ba!$(UHGQ z6eC4;FF_r|Q^r(vkq`sMf6Q)y>YXczpVddW<~l*lFtMk909TKX<MP2FOy_cl8NuI@ zODPJC#^z?d{;h`Ne0i}@eB|A;GfRS-($MHY6S_tu+_89{IiBpFoz0A0?ojvFCsPC0 zW@E{esJpl7G_X|Nz|-3&v48bvc(%C2dF%)wb3oj1MkH+6b#IDVh-co)Eh1!@k)iT9 z*}PG7RuB>U7y>%-Wm(w*Pg~g&qSA-!Ay5W<i3~6XJ$1ADWrS}}s;W<vk9}VL@2#h? zb4lKWX<<))Kdv61#482{F`3OGDcC@T0w^^amE}t1UoArZ?pUGt^h&jQ?6$po^j_r} zq0oe`(G%`iyw99W4NlKwM)p>n`XBAej{joHOavH`0;o9+tk;V;R9wRSXP?27TPM0> z>;i)7azGT%n7!7+v^C!pGH+598_DjKP<g$I^q%zZk<f)#6y9h+9zSj!rfWDsl1{oP zSg;p@4Ud9nJ!bJ{D-t6{xZJ9&9=1N&HOVs)$WK`ot{fW1H4{6q(BF@tL=p+X1}Xqh zwQc9<cH#b%Wq#sBseEX;Tt1<RT%#9gLf1GaeDT-==0vK0Vl>&mx8c~I*w;68Rl*F; zUk6%U@x^8pM@wh%y_F~N@cQ8vvGZ|gk-LC<xz2c`f<~Q<3}?^%auw6f_)EemY7q<# zVOm=b^=MPJyPM22ml-2akU4K4iDiVZ0LPN51j0yom0n)m;dwfBv!onYb&h{Wtu#W} z;7b*W%gH=tS$M<P1l}?^g}J^wa`CvZYaIaUjzgc_-1>3MH2!F{QayC0Qd$1Mo&`<h z8a+c3y2kUu7mnR;?o160#?9F4vR3l1cIPHv5f3g84*+nei<;BKQgs90S$+cFJ@X`L zP6Oh`wU;SyqBMcm&JcmfEBDgnvLooGoO-2_qqrBw=?phGLI~2=8xlfNyo~l(erFXp z->PhqGD2e_YQ5cS;%Iih9Nz<Aa3mhq3lKC~<h=}HGEZ7DymiM;ykqAyCNdc$OiQ@B z8_?R;^tr9AXUewyhYj0#>{Pk5aqAxKk!zegG@)yp7u<XD5hHEIvzB4Kdonrj@wx2i zd`z(79MEc3UFu@1QNcf-ehlAQ`Z2bf-fESiMl?#dv<M`^SiP5%UDZqx)h*Qt3hz%O z$IV^!Ta(}a22@IrkQj}0jK%>2>5x<yUE+{*lrTa-L=>bQF+h|ag1{(=Q7WTL88tda zNDBxk0)C$N_pkV#>s;6K>wVqV>%8i`p8L3pX|bp@&Dd8!CPuu@i89ra)x`+v=qZ`s z(l1=si|Pba+HROHh;D*6wnUF*<=yEDQ#d7f!uB7a4Sw=8uAOv~LZ^nfvAH=q>Uqz# zR<}hUj#<1iEGh5AZ7xeTTNbgzVFLZp(NhOl@&>)>56%sq2g)a!-m-b^zR){|qd7x; ztm2Yvf{ZV_o6M1%p)SY#9rfohH3#J@aZrENzm0hn8zVvSAp|1#{L#;HF9C{IsiEC@ zVdJj@X$p;tr^CV!?kN!w+r5Los7FyW0(8#w3Rj6a*UYzA!pAP%oUH1;S5+L@cDC(U z>kH7KS*AP~Dbhj2biOaMrSAU2t3qj|{^hYJ^Y@$FRflhOufRl&F{ysz-ivL>Z+UM& zJ&)~C0sKhMH9SwE#%ucSdcXXUr1OO!_to3t3TUNxrmR2Grc+->3A7#I>xO_n=<8v9 z4*IEBov;nP6)EzcR9aznVVy@Q=kt4`EwdcI`vf|hktK>Nf{UJ{^#v6V6YBgcxev5E zI<|izoo-&*mo@Fgi%_RLtjMcJuqr!y#3zxd9PJBxg2^HnUj8ErRlWa4xgy^7G?WEs zW%M{caE3z6$d$3PWhy5p@$iF#^zM~^faXm{`0PUaQ!P;PbqauTcJ2`F3-ZlGOw>aW zg>%)T>DsAY`p5FVw&L1CF^Oc8TY74rf<X+}JBjIQNS0lRtrWzAV49rk@dK%O?8ygT zDgw-4HCLx_um3F(>YYoed8<o81Z>SP_p)BEEvWpn`A*^=hm|xfiqR}mTDg?G)NlB^ zZEhNUbaHDyQB*dwe|e)v^dNRLfKD{#ab?J-(hP`W(@fAjrg+vNH4ltdhj~Kyntk@2 z`yH>*Cm&q_5X*?|K`((}ItBb^q}}59HqBS<&ZG^gFh4bKvzr={?|PyqJPr^69FLEg zX@_awVugamIwx}hQO32fS5v<^><7NcHmdCl)Ap2m+4Q=wgn>{^--MYi2IPyLLPw9y z2aVMNoqfyV7NL7#k-_{gJftU^jJK-J(GLaq?!m=!y7Dfy+5!;F;eV-6j6*!9F0ImA zDfOn&_&A6XuZp?E#jsRsu*NN^g2I5jLK-KM-q-iNC*Mp;DWm=#UY6VBbhQl$^jOXq zby>QhD{@1hYzqM?b~G%LzH-8th{%|6IuuGXm=Qjj{MT(xqTsMtlo;Y?MCA)eyuTHM zBWJYuoI#B@9Iw8<DKt3ck@e#XnxWNW-MJmNzU4FqJc$+kTw|hsgFT7d1n$C*>bfug zif5V|3*zosixJGed;L^&s{lT0+Kaq5ox!WtTzlDNfjgi2+*Y&ET=yon=h}0Tpk#K| z2hc{1+l=2j{M1#?)@vU<tG@o!t;gh7;$+h4l10MJ%-h^^>d88<+}?dexL{h6hxKvB zd(2k_yW2@FBV-XTne@4-`|$&oo8@AX1A;;eWeayC<0kkkpG~yuO|<_VdNIGl6fRui z*0o0Clbm=eng%lVs1;1_&O7Hnp{IKY&5eQUQa5fB>gMO<HS^RQs(9_eh{exV)lq9% z>?f9(SBi?#vVfy=Wcf{~y{L5rBfC?^mm1Q`qivYAo%7{xDi})g+C-KBhp+Zf;s*N& zpc@M|Lr?jCY>D61e-)pxFA#A}S$1lc`uJRsF{SbyKiNq2hsw5+8yIZSHJH#7ajg*A z{JZX!I>H0>2OqBWei8&xqDntCTypaNNEHR3;w>R@e>$FlSE=OEw_}89{Et4CO$Qgl zl~Q2|23Z4`eCf==MR5q%y+{`=sur)d-$3LJFken7W_Z(K>m8wtYITR+`SmgT;YCE} zC+GA;%$W)N?q?g?0`IASqPmoBf<#Id0JrV`>_W+?X5P9aBB(n3CU0Ny+2*e$r@t*k z{HmTDoo=kr%R>sg6%WjhJ&|)uEt#n1IGH^H!)e_F5}7K6|KcK$TyAm$mcv~d7@0kM z?CJrD%V346N5)y$BNS=rd&An6p;Ts>M)xWwyfwfOP7mMN)_VYAN5%gTkFF#p{vE^j z&#?yPj7q|+&u^z}U&7V%ocp@d2<3j7lEkX<N)p0{%foxt_9J2?G^|SRFq3|qhibsf zZwIGH0WAuVsfrO*?>N;IhNX$7VQID5jBGXq2wLmQ3Hk9)2d(xUQE>xD!b6}^d6l8n zLt@S@{t+~>Hi*r&Tv5I@oAA1b%n0~ppw(Oh!F(9=(MRK1rETbwD(mpA$ye>HURw0Y z>`XusDoryNxq^yE>F(A2*&#l{H&hoE>~kBhdl0MzesTFWLm*pjl@p1!RjmG%ZLxyg ztYEZt?L=7+6nEu*FiHPb5Jy;og_XYM%LBhP3W+*JG{|a<&^btXbl~;k^|LbSJ6)>m zUA&Bpt0cpr<6~EwMKbp%7a+q@*>@(c{3u;Vroz2KxYFjd_nI>KpWr#!sAgNDvwfBI zjgFA1&L^G^0hk>B!4#hh_(h)9z^vK>y9flF?dY)npV$(n@LpR94V0p5;i3YDMXxm$ z2o$-;@@7^_KOGOiDOr>LEp_o}P9E}CM*A|`d4or=@E0SFM+=W+z3=u8O(z!BK02WF z)fG!@2c{1Mg8Ge9)>Pm2ul_-f*aqx)hA+3CQPv2K#eLOfzK9okQrj$FGpsXQyE$#- zhFe$u2YqvQt`&f*3M&VrbBD*8cH2!t${#z*|7QaIE5^MyKz5S1RWgCM0#ZHP6M}aq zFGJ6=^wT4C0{WqcV6o@1W4is=V#Jg=ViL%jJ4aXSxWyZLmW_ws`bnv%2rvh<uKXbP zzx9a23yWLIo{!5w-P-rgV#Ed&vmP5gSsAt-?;#`Cf}p>cH1ZuqUSto_yU4%Slg`te zNw~$8DCqkZ#n})``aa?9=F@8aS>|TqB5uBnN5e@vzg#ibcz?0orn&+f0Q8hvdW<Pf zxud}7MB%tn`IxY{mhi{Hq{zsFUk)M`7wKM-Oe1@q$?Zx`RLEZaVXvYUAj_ZbTJEI1 z!EWQ<?9cW}L_^Y07mk1iN`n+^WPFSHl@}A9v_I{W+E<&=mwX}YGabKD2piHp#J^Z- z!E@q5nXgC25a084?saJG^sT;Wgx}3(V=j%)W=j4d{@keEE5AGg4HO}#>1bq=VPD}G zh7epkZTs2lnU(>-@FBqPK^opBMFW1^ZLxV^slIt1YK@rm9qCSMGQm)t()TFDi_O>Y za&HxFLTk!nO1D=`kX*gS+q?X&$ai8s@OnE+OdU2f_Qx#j>(kjW#~_|td0|<MnWTTw znM;<=cLa@_rB!oN@3{&Y_RP|FnF{BQtjoRM?KP23%|U4N!0c>efl(<&1-k46t7~ER zjcV<xC+=k?P#Fi4@(|!>sfK+6IYu~Z1VmEl+kUO!^|9~GSAo)+B%Cb6eMj>Q?iDDM zsSs#Qum@Lle2_t(CG%`X1EE<5=S)rE8FrBIG)kP?sCJ@q$<~YBz_>!$-VqP?qOWKW zc$+dStiBwIqq5`7-$RMr`&|^s^g1<3uXy8Ypp{aTa&%&!x|vCmP<{3;*Ov%ivOt{H z(E1rFRn&#~%F9oAH_Z`R5-~dBW-LwDjn`Imy7ftZ8)s*qojnzI8tl8p6}d*J*qsY| zyKXzz{YP?L7dsoD5S!fTI&d?_AX?`)jp8NVP8)DDfoB)UYP$R~6Lreifubd6ZLz+t zxRzI$-b@}JXKl;bYNy5Um@1}UlQT-^wa?2UCBNv)(OSCxmXK#akrb%a_FK42rUaHJ zPl~R@v-G5?Bz>p{-CL7I55NW9<8`5N2(WZ>oTuj<ku3^;9;5dY-ncePaUQ#Bt9?lb zSCmKVULk|DBR1ZF<OU2(aB`BVhpax&lqZGDTd%Bt)m<M}C0rcg`yKPOk`%>E8MVO^ zosjl|WuQxxRbwIL(qP?bRP}tqp2;CuB4HQ`Y)&kF76EbqYxYgtYK_$lS;Vn@MaJx$ zZ<1lI^7}si>_^yK-D8&jZnpnjo?33Ei;fYr`}ry*9cb4_H_)0H7fNw)z@neVkyKg- zGHtj_5t2uh#_L7vh+{Hl$hM?0naB1R{}xARi+T0JgT~xb%iZ;QzJ)-{p88biG*C0e z#**c$K6x%QMAV)%Y768?;oRjXG&E3K-*Enc(ijd3A$oWh7!GPr>Nn7mJX_H3#}<ww z3W$}3bBKZ^J(7}l8IfMG{CaLnjT2SlHc!(f#OcGG%l*y(2Npl3D{}akhIF>E)0|l% zB4GHZ-tty2amf@%a7tySrZk&@$mCl}bh7Z924+-oe|U?Z(L>l2QryR)z@5<oqM0z5 z2@k+oKwIppFKXrx&sx`saT;wKM!V6EJ^cYQDP&@Lpmz3ClaO=~A&m}o0wNvAa9!Vk z8CPkT^engKf^0aa>uwL-nA(Gdb7R&UNUt#@PaJ`hJV8XR(b1@BWYP%J;JvmJ+#cNg zNQtjv`Xt(c9ZQU;J)Zd9%u>L`L!Z16t;)`4+Dm^l@QF3bR2^*(GJ4c&0K+-X)lk00 zDlA#d7*NYo-W^aJvTf5lk!hTfp#~2Ba&wB#`%+_bjOMgZi3>-MJHA%woAqG#@zZ0I zLi4Cbgc6@$%N~r6h{QQtTj>Cjdo+NWry42HfHy&Sh-lI&dnz<c97)Oq4R$lfTpR?s zi=pCkyLKvChs|e^ROGAl+VUcD%p!8&LD^)GT;HF)9*xC<j3PrP?^f*g{i$F_`;cWc zd7Tea9ZJ^KgJ+9n^6^AZaIw8Kgp<py6=xB$la8DUYg{MxYP9{7_)h_uq_(o+ds|V_ z8UA}^)PS0t!z_C;VjyYvZtlSW0<7|;mN_ShHPxfCIVWD&B#wZ<H~jUP>Q~KJ7sJ?* zd1>Dr;1|-;1QQavl;{|>si|-6lB_dS<X)dPO$aVouuEe;@gNMuzh4?V%|Jg$V|@S4 z1&dd~3TO+osl{_%vPi)Zy{3-`g-R@aA@Azug9d_&&3z#Q7<bqD6~&Qp?!Q6v0Vx&< z4GeqFFudE7-$SDTuckv1z;EP*cLDu24`x?ccMxE0JE=?x>`KFk&Kd%Z0y>GyeMl(w zAtSzqTFwN|kA4VZlY4DQ2j>86@lEza0r%{yWN)!Lx!CKu(D7g=Whn;Wi*$%82RKBQ zZ3DH9T~lsD%XS7A7S`z0MD(ARnngl*wtR_Lhx4DERwIcQm5To_mNVP$e-9p!z8o-Q QDUt!pP|r*ktL^gQf3w~P2mk;8 literal 35899 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 diff --git a/pype/resources/icons/circle_red.png b/pype/resources/icons/circle_red.png index 99d01b3baa375d18ade84ebd7bde833589ca3281..ba8e9c8fe7c3835e3797b5c621ebb98f4ac13195 100644 GIT binary patch literal 127047 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 gIev;}q3Q1EnYIJYaG|Jr0sjS+V<O(xChPNd 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 literal 36200 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 diff --git a/pype/resources/icons/inventory.png b/pype/resources/icons/inventory.png index 34f6488233b392963ce954263e0218f0e0079885..07e0f9cd180ad998f87bb2eff9e546b6ed32130e 100644 GIT binary patch literal 57718 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≈eS&ieoFdFgjDQ)c6f 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 X?l1s%qQx=*m`6iZSEW+P=HveWm*uZK literal 15767 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 TYG2O)(U9<v2+f+Ho`e1mfRfiP diff --git a/pype/resources/icons/loader.png b/pype/resources/icons/loader.png index 1988fc76e92c456b3463cd985a02366012d98ee9..f3acabb23331942dff81dc6cc698817da2d0f806 100644 GIT binary patch literal 60326 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 a?qz_U_rWwR)Qt;(cobz-Woo2Mg8v8m^`RjE delta 398 zcmV;90dfAO*8`XXA&F2<M-2)Z3IG5A4M|8uQUCw|7ytkO76=9a007#3T!@pd0T+J& z8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0VPR9K~#9!?3K+8!Y~Yl z6NJRI+(EEG8KG>z1|YEjqc8x7j=%=(2xWsx3;?~ssXP~h`ja$C=@Cm-M2x?eD7Gu} zJQpT=9;XW|XZVb_F7VB0dreHa17Uw>VF^y=^PcESz_;A%EYR8h0!AB_N-?0)gU3{o zD8ai62>BkC6`VLB^5gFf5F~H}U&Bu%!U-<$m~)8{F;mFLVM4*1B9EFWpqt>&%5FqV zmf)(g9g{%7rx!XA%>fEP3!H2zX;k18X{}T1B7TQhh8udHDx$~99J<&P%lKmE??>jL z6|{)BSjKOcRQjMNkqW%gXg`WH;L1+!D58XGM}?z^7T!9GEJa%3#$jg=F~Y5;sYb*K sUd$q!k3J8yIhGy&+ykE4<h=wK00GB;6TIh{djJ3c07*qoM6N<$f{~A=rvLx| diff --git a/pype/resources/icons/lookmanager.png b/pype/resources/icons/lookmanager.png index 9ed1d3db8ebaaed66efbf4949ecbd1ee9aed198b..c929037cdff4194c25f673ed51b45ac0265bb5fe 100644 GIT binary patch literal 42562 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 F@jt83q__Y8 literal 2408 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 Kxi)8&F8CKzT}2}R diff --git a/pype/resources/icons/pype_icon.png b/pype/resources/icons/pype_icon.png index bfacf6eeedc753db0d77e661843a78b0eb13ce38..c3ab1d30025adafc1c7684c249540dac6a80782c 100644 GIT binary patch literal 110945 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 $@U*l;|{0vayb_2~VYwh)n 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�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 literal 3793 zcmai1XH=6*x6Ye{CK8MY2ok{)4xlKAASI|oK|&G1NG}mf1QaAla)1M9Vx@*AARG=| zP(e_zU<?oijI;wmJ_8;~L`swvsfmEz!TaO>xodrEz3*Bxd-m+vduBh+o{4ukPEgpO zz5xb<DcIZD5MeL~TK{FGfh2Nj(;Dbp3$nI$2`3VcXxSgNHZ`&^HQlq%zz7D@OQWTA z>D!#x!nHCEY!;)_rS{8J6d7GObJpmL-tP0Zl4m(l^NyV<{AlB#8n@>Oo3}NptV#uE zJ|o&Vn3{fQzV*eT>weC;f2IfKUk*oieHjXWt$u9R&iap152)_*D{Q9Z=F!{JIe)SO z%hR$_iz|#7@mk8$pHYcwq2D{bGrQI<E~eeDqTh3mbUpE`QdBBhxZu7&%BRlB{>E=_ z%HJG!GSG{;`1R9ojdwK+=dxS9yRD=@oIg!qCpD2PwV&R3%+AYq-B-Rk#EpqRn42$e zH>EOb!%a~%M3rp~*r<3t>D^S3rWvB9_(;Q~?$xZM(Ovs0MtPn)j$hk-{6skM;4UMb zKV5Cp+5JBoWB+s3dgcu6mFk83jh`Q>2K%`5nIv^tH|c2{{two-)KQXy*m^}ZwzhO} z%KAMn&oAq#2$dI#=U!LuIbuc3tlO`0ov#$=N&j&1zR#|usfdEl(Xv&o9)7Q9wlB0w z%Em%{ivvE5@OL~0hayL@^9qN-46y4z6nW3;4;XCYqP@*w*T}r-!K)%N&5!#{x9*){ zhzXWASaS!qGo?GY?l$su#|0v%Q0;A5E;A>?*mVC%wJDSL=4$tivf}O;AJ@fXsLA== zEOKfsx|h|o`;*Y?jJ=BV+1DNTEg$G>Jk1H*o>$A!jmun%;blqQN=!%I)jzUkms>fp zv0Vq3qr0T+)3yK0Cug|}C!j?6ZI{>BHdqu8$!bfOwI$r&7OTOiU<}94bfcG`6vVJv zxW<nOMffYapPTyu6=KDMM~NtxeIKAMP0Y#m$+^a@3U5wx5pM1p!Is3@aAfbZ3|ns0 z?KQ~|+hA7u5_C!WxtrIMh~$57ILq{EIzumb8{c$tn7j0sxH@}e2>95=t({(PROyoy zmEu2x|DjmG9bO;u*B6;_lEHeI0b@M^LB{T+rwkh{HhHXD-M&0Q%aJluxD^0*=x^lZ zVPe>A3EYyi#IYPY@i|(&iE@>cojpdA3<wLiSise<DKYfJHja<T2HI&{w=jpR7h7`$ zAyIxyGao$)K(|JTkpg=$PLn9{jAF-R1J&5-Vj?NqW0V%<OFcGh4)<2!!m<&T^Q@Ry z>M=0G+f)}(&^0+{ILA7mgDX?ifc8`jm%MZrr3+I7ne?oFo!pC3p>e4AQQ5%$dRX0Q zDvz@Blmiu6I)2b38^H%lO$qNl8<(~FIZO1vNXqU?M0q(f=?llI@4fV|+krdx$Q<62 zwoi~4<(Iz|Q=_5*1+h;uw#~B+?7)>?WYVA3IC0A7SQ-m{FELP1jafHaF6c2(qJ_3j z&N-K0StGJ`?<Jqv2E*GiJShS`cWA%$s`A<O1`nUZACoV!{x~XYS1UOzDB+<)E+b3( z{Zjd3p|*slE$Gzo`RpjahTXVg1t#63U;?h$KDkfAb(#AKCl-d&BWww~+t8^h^HppE z=R~IG4XoCl@qW&$60FK6S-Zqn+STpJJoG%U*@BVsMPrN%3HS@#t}$BF6>9SV4d}r^ z4_ldzCUok@j0sxQ32JjCkonCfpzda3wVq8Tu?^;habD(d;>s0$oWBZ_-rL|f&suE| z#sygbVLpOwfji?3#K|vgWsbF@Q(0l|r0f72!ZBczHJ>G<2Z6~E263pnx3F5YiF;rV zH)Ect6YyU@7~05Gz6DxivUZL$t89amWaiyw(5JyEm#EF!z-WCz3hM4TKPr8ENm;<M z`0=uYF<UM%f22g<elf9n(wppYROZ--Z0W^-Oyx%dW2V*ZG)@l3Ifcnb7zTd6C{G8$ zf$=zy+)zXkvx1;nV^AhpTjuu+*qxk@zCy~jB9dDWyd9s-;kYB2%Fb{;9OOgPJ`qWf z-uH0yZ)o8%lD+qS{KLvVKXQv9LKXf~Z7}1paS6g5B=9ab_W{_dxkw_+vRPch++@<r z+{rDUO#+Z+wlB2bp}Y4cRjK-JoQk_--{CmNni`XGC*X}MYDR)`m)oqA2h&r}23|2M ziO_&L@3kfTt-UIVK5S|ulk{0O5PcPOU^^x)b&&@F-*SC2m7^JZco?}bq={WY9Lg@v zS;oZ943T0(&>lJZOUK(TQ+b6EU1GWUTb_^}rU5-W?M%i0#!NwN<)U4-ZBIhkHHZDu zyl@@67el~bUu@(-@uDwu>B&+d-6m3}@bzV6S*;<?UxR=Ti98J^Hz;HFGO>lGtAU`i zJ$c<y_mMf)0PGwO6E8Z3zrOHRNWTF<TPk0S*gWzcQg9??m-FUR`o5}lAx+FZJ_UGm zyfKCp2&C-lrb(!F?ijvl?|0W?XWIy{KQ7+^WaY$!RjHyVF%=&KGF#?3LYMGD`(btf zoYc#E2*%a>Hm=J3u&RwC<;#gRU6lZnG?|zw#X3<PN48^PkukGief{coCr&lIQTl+P zd4TL6wlbB?=uNPau2xIsx;x{quQ~+t1Thvk|KFK-mgy+XVsdhUz#AAGj}#zt^;gRg zhUIE>(val5R>Nk@<IMyuzlmhjy`mRbf#VJ0G73hcHah@ZM86^w{M!epp|}3u5`<0| zvUDaS8TG$8OCPUSsRx-n$f|8i0MG?#XE*qD@gzh+mR7A<Q#lua0n3!0c@Jq0$nk|` zH}|O&rf2dxD4KZCd!Tk{-~_qlZyx$rJ4PGlzmBVhPy`=X1IYTg9KTCHKaP1f3n0@l zryMSjwF_Bs%~Y<hXS_29s`=&g_7d!Q;Ka1VB~y9%D4_#T!^dxWq8VXa6o8@SkIJ?L zLNRvy7d2?s>EO<g0DaXBKdKpN1u7Qso-<WdH6yo#aYq5=t<E5S?8TiqvCccQuxxj) zZ?4pL#emojg;v*$3<={*fzs5E=WPj%iOj%6tX5~4^bi`u(^+S>gPg9i1=CLe{XNtf z1j&QkVpeSZ5s+-fin_=c1Rsz3at*8Hw6v*HjRO$q2X-@a&8%}j{V;n=-DUz_efD%N zRA>2%VX39loVUG~luQA8{aL1nnDFrWMxnm*_EN=YEjDLxEFV^i13^C=sojV0C6bTM zS{<&FKZNP7S<%g%_~~c?6Xejd_<Y7Na6E&zgLgowyQW_;W|Mg*6bKTZeA%)y7S^x@ z)1#X&7pNAa5V?)=96`|rIeabx?g8;Z#Wci~Rck;BornGPDQ=m{r;?cV3~XVMSXvY$ z$lawslfbl(#}?k1E{YPIQXKFmw=e|x+Msy0Uh&rzN#)A?m<A;|$;qJrTX-n??l`&r z0(HRX>B`C?uoCzaF;({R_HYr`qoOi$@4jHbxL;WEVqa?WX%sA)p^LJ7yVkG78CtK> zrC*~p7}VI8Z3&$`v_nCok=`B)0^a*FILT3PIIZ9m)5DRazfS;K{Rf?zl?O_~|F7T^ z|BMO{wjt7jvi&jSdG#G6>fXWK?!S$)>=H^Imkr!GN|Wr?k{Lq!BJ=irs&2g8Q84%y ze@sPC%L%b&sU=_w4{uxR{rS7VLC`DJ(3=8X-HU6;<&T{geBY6WiFCqW&*YC;a2k6C zaw5|p^MRcl8fS@Z&=vA+^42<iWbntrIHwSeyu}yr=K$DYf*0V{afv%ztpv`&WsVhN zM3Em<<P=@Oh$q+v{Oa#!(STO{M`<t7eNgZQ@lpU}2_n!JL>o4vyS0G38778fA+jBw z&f&JAlMDspaO52}+u)SVyxK-xn-?%H!pGLxF<l_57X&U^j`KyOR$B%y$0=|EY*qE5 zyU;FQtDt|F%&ljYL>|A8c&8G~mSXQ`oxS#3b^9SyudzAYp+{&24XX|s-CR!gj&4W0 zJiL-Nu7Hn?Kv53=DqQKt-&?=u3z=%{@~!{`lTM`Sh!TWxYI&&OB&H`wlP!K*Fnezg znOedfcz+cm#=HMLPr%!Q>%u*b8V?g5d6blGn8;iw?h7Og<}p3I81Xg?c_&wUxXQAp z{SN~E!Iv>akVAcN1Q3!ArIz*npD=A1=b45r>@AI{n2r5K_zs=cJV;(heg&ilG=MqM zbFi?J;nm#Z53;9$d-MKO4t(iX<<Z;!Z!toJ;z;EHN=XOR(V8<2JnB0^z8L@~IzG3N z>G)L3gY<zn#Y2Y*b%Y_cAe?FVLlE8+44_~=yir%LuubBU^$iH`9RP%x?n-Vk6}%NP zcMgEo9v(Ua>|#He!w|;Fp?XY~a<PTy+`Ph6DQ;9Qa<;mrn7K}kg}outmlD8X=*#6v z(XoZi0EU`kWx<Rv%X$F81_&TE(8LsA9?;8K&P|S4i4UDXmj^lIPJQ<jpcT~gWw?cC zmZA2F?&RjaO7L&$0Akxr<yVZ__^2-;9WBk|6GR|#$W$IKlRPcZ_xj5xZCYl?aej;7 z$$s&bM?QdKo`q1KP{K*snuscx!Hm!+R=UrZ+)~AC_>oINns|b10Kzw&Kh|%eN&b<W z)v)l0Lw0iy4*fED^D@#T5)4b{nSIx2k`Kx^$df;CvCS}yKF(;A68i%8Xq(kbQ?QS> ziL-@qNbT4S>P2k{D-1=L=DW!`nZQGQ%GwTYVo+7abkR#q!7>xD$ik;F!hd;6fVT#2 b;3u>qRjE!lxug$XMKJrL$8D;P_+R@UX<7IA diff --git a/pype/resources/icons/pype_icon_dev.png b/pype/resources/icons/pype_icon_dev.png index b452eb28120438711058702fd87e4c26a7cb7f62..2bcf342c20eeec25aece75ca2cb1ebc896ad5fab 100644 GIT binary patch literal 109276 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≀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 aJJOC%dM;$I#g74)NBNzGe9aq+u>S*%i6pZC literal 6890 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 diff --git a/pype/resources/icons/pype_splash.png b/pype/resources/icons/pype_splash.png index bfacf6eeedc753db0d77e661843a78b0eb13ce38..d44ffb29b45503f6c5dd770d12857a3e164167b7 100644 GIT binary patch literal 82287 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 F{{z%TE?NKp literal 3793 zcmai1XH=6*x6Ye{CK8MY2ok{)4xlKAASI|oK|&G1NG}mf1QaAla)1M9Vx@*AARG=| zP(e_zU<?oijI;wmJ_8;~L`swvsfmEz!TaO>xodrEz3*Bxd-m+vduBh+o{4ukPEgpO zz5xb<DcIZD5MeL~TK{FGfh2Nj(;Dbp3$nI$2`3VcXxSgNHZ`&^HQlq%zz7D@OQWTA z>D!#x!nHCEY!;)_rS{8J6d7GObJpmL-tP0Zl4m(l^NyV<{AlB#8n@>Oo3}NptV#uE zJ|o&Vn3{fQzV*eT>weC;f2IfKUk*oieHjXWt$u9R&iap152)_*D{Q9Z=F!{JIe)SO z%hR$_iz|#7@mk8$pHYcwq2D{bGrQI<E~eeDqTh3mbUpE`QdBBhxZu7&%BRlB{>E=_ z%HJG!GSG{;`1R9ojdwK+=dxS9yRD=@oIg!qCpD2PwV&R3%+AYq-B-Rk#EpqRn42$e zH>EOb!%a~%M3rp~*r<3t>D^S3rWvB9_(;Q~?$xZM(Ovs0MtPn)j$hk-{6skM;4UMb zKV5Cp+5JBoWB+s3dgcu6mFk83jh`Q>2K%`5nIv^tH|c2{{two-)KQXy*m^}ZwzhO} z%KAMn&oAq#2$dI#=U!LuIbuc3tlO`0ov#$=N&j&1zR#|usfdEl(Xv&o9)7Q9wlB0w z%Em%{ivvE5@OL~0hayL@^9qN-46y4z6nW3;4;XCYqP@*w*T}r-!K)%N&5!#{x9*){ zhzXWASaS!qGo?GY?l$su#|0v%Q0;A5E;A>?*mVC%wJDSL=4$tivf}O;AJ@fXsLA== zEOKfsx|h|o`;*Y?jJ=BV+1DNTEg$G>Jk1H*o>$A!jmun%;blqQN=!%I)jzUkms>fp zv0Vq3qr0T+)3yK0Cug|}C!j?6ZI{>BHdqu8$!bfOwI$r&7OTOiU<}94bfcG`6vVJv zxW<nOMffYapPTyu6=KDMM~NtxeIKAMP0Y#m$+^a@3U5wx5pM1p!Is3@aAfbZ3|ns0 z?KQ~|+hA7u5_C!WxtrIMh~$57ILq{EIzumb8{c$tn7j0sxH@}e2>95=t({(PROyoy zmEu2x|DjmG9bO;u*B6;_lEHeI0b@M^LB{T+rwkh{HhHXD-M&0Q%aJluxD^0*=x^lZ zVPe>A3EYyi#IYPY@i|(&iE@>cojpdA3<wLiSise<DKYfJHja<T2HI&{w=jpR7h7`$ zAyIxyGao$)K(|JTkpg=$PLn9{jAF-R1J&5-Vj?NqW0V%<OFcGh4)<2!!m<&T^Q@Ry z>M=0G+f)}(&^0+{ILA7mgDX?ifc8`jm%MZrr3+I7ne?oFo!pC3p>e4AQQ5%$dRX0Q zDvz@Blmiu6I)2b38^H%lO$qNl8<(~FIZO1vNXqU?M0q(f=?llI@4fV|+krdx$Q<62 zwoi~4<(Iz|Q=_5*1+h;uw#~B+?7)>?WYVA3IC0A7SQ-m{FELP1jafHaF6c2(qJ_3j z&N-K0StGJ`?<Jqv2E*GiJShS`cWA%$s`A<O1`nUZACoV!{x~XYS1UOzDB+<)E+b3( z{Zjd3p|*slE$Gzo`RpjahTXVg1t#63U;?h$KDkfAb(#AKCl-d&BWww~+t8^h^HppE z=R~IG4XoCl@qW&$60FK6S-Zqn+STpJJoG%U*@BVsMPrN%3HS@#t}$BF6>9SV4d}r^ z4_ldzCUok@j0sxQ32JjCkonCfpzda3wVq8Tu?^;habD(d;>s0$oWBZ_-rL|f&suE| z#sygbVLpOwfji?3#K|vgWsbF@Q(0l|r0f72!ZBczHJ>G<2Z6~E263pnx3F5YiF;rV zH)Ect6YyU@7~05Gz6DxivUZL$t89amWaiyw(5JyEm#EF!z-WCz3hM4TKPr8ENm;<M z`0=uYF<UM%f22g<elf9n(wppYROZ--Z0W^-Oyx%dW2V*ZG)@l3Ifcnb7zTd6C{G8$ zf$=zy+)zXkvx1;nV^AhpTjuu+*qxk@zCy~jB9dDWyd9s-;kYB2%Fb{;9OOgPJ`qWf z-uH0yZ)o8%lD+qS{KLvVKXQv9LKXf~Z7}1paS6g5B=9ab_W{_dxkw_+vRPch++@<r z+{rDUO#+Z+wlB2bp}Y4cRjK-JoQk_--{CmNni`XGC*X}MYDR)`m)oqA2h&r}23|2M ziO_&L@3kfTt-UIVK5S|ulk{0O5PcPOU^^x)b&&@F-*SC2m7^JZco?}bq={WY9Lg@v zS;oZ943T0(&>lJZOUK(TQ+b6EU1GWUTb_^}rU5-W?M%i0#!NwN<)U4-ZBIhkHHZDu zyl@@67el~bUu@(-@uDwu>B&+d-6m3}@bzV6S*;<?UxR=Ti98J^Hz;HFGO>lGtAU`i zJ$c<y_mMf)0PGwO6E8Z3zrOHRNWTF<TPk0S*gWzcQg9??m-FUR`o5}lAx+FZJ_UGm zyfKCp2&C-lrb(!F?ijvl?|0W?XWIy{KQ7+^WaY$!RjHyVF%=&KGF#?3LYMGD`(btf zoYc#E2*%a>Hm=J3u&RwC<;#gRU6lZnG?|zw#X3<PN48^PkukGief{coCr&lIQTl+P zd4TL6wlbB?=uNPau2xIsx;x{quQ~+t1Thvk|KFK-mgy+XVsdhUz#AAGj}#zt^;gRg zhUIE>(val5R>Nk@<IMyuzlmhjy`mRbf#VJ0G73hcHah@ZM86^w{M!epp|}3u5`<0| zvUDaS8TG$8OCPUSsRx-n$f|8i0MG?#XE*qD@gzh+mR7A<Q#lua0n3!0c@Jq0$nk|` zH}|O&rf2dxD4KZCd!Tk{-~_qlZyx$rJ4PGlzmBVhPy`=X1IYTg9KTCHKaP1f3n0@l zryMSjwF_Bs%~Y<hXS_29s`=&g_7d!Q;Ka1VB~y9%D4_#T!^dxWq8VXa6o8@SkIJ?L zLNRvy7d2?s>EO<g0DaXBKdKpN1u7Qso-<WdH6yo#aYq5=t<E5S?8TiqvCccQuxxj) zZ?4pL#emojg;v*$3<={*fzs5E=WPj%iOj%6tX5~4^bi`u(^+S>gPg9i1=CLe{XNtf z1j&QkVpeSZ5s+-fin_=c1Rsz3at*8Hw6v*HjRO$q2X-@a&8%}j{V;n=-DUz_efD%N zRA>2%VX39loVUG~luQA8{aL1nnDFrWMxnm*_EN=YEjDLxEFV^i13^C=sojV0C6bTM zS{<&FKZNP7S<%g%_~~c?6Xejd_<Y7Na6E&zgLgowyQW_;W|Mg*6bKTZeA%)y7S^x@ z)1#X&7pNAa5V?)=96`|rIeabx?g8;Z#Wci~Rck;BornGPDQ=m{r;?cV3~XVMSXvY$ z$lawslfbl(#}?k1E{YPIQXKFmw=e|x+Msy0Uh&rzN#)A?m<A;|$;qJrTX-n??l`&r z0(HRX>B`C?uoCzaF;({R_HYr`qoOi$@4jHbxL;WEVqa?WX%sA)p^LJ7yVkG78CtK> zrC*~p7}VI8Z3&$`v_nCok=`B)0^a*FILT3PIIZ9m)5DRazfS;K{Rf?zl?O_~|F7T^ z|BMO{wjt7jvi&jSdG#G6>fXWK?!S$)>=H^Imkr!GN|Wr?k{Lq!BJ=irs&2g8Q84%y ze@sPC%L%b&sU=_w4{uxR{rS7VLC`DJ(3=8X-HU6;<&T{geBY6WiFCqW&*YC;a2k6C zaw5|p^MRcl8fS@Z&=vA+^42<iWbntrIHwSeyu}yr=K$DYf*0V{afv%ztpv`&WsVhN zM3Em<<P=@Oh$q+v{Oa#!(STO{M`<t7eNgZQ@lpU}2_n!JL>o4vyS0G38778fA+jBw z&f&JAlMDspaO52}+u)SVyxK-xn-?%H!pGLxF<l_57X&U^j`KyOR$B%y$0=|EY*qE5 zyU;FQtDt|F%&ljYL>|A8c&8G~mSXQ`oxS#3b^9SyudzAYp+{&24XX|s-CR!gj&4W0 zJiL-Nu7Hn?Kv53=DqQKt-&?=u3z=%{@~!{`lTM`Sh!TWxYI&&OB&H`wlP!K*Fnezg znOedfcz+cm#=HMLPr%!Q>%u*b8V?g5d6blGn8;iw?h7Og<}p3I81Xg?c_&wUxXQAp z{SN~E!Iv>akVAcN1Q3!ArIz*npD=A1=b45r>@AI{n2r5K_zs=cJV;(heg&ilG=MqM zbFi?J;nm#Z53;9$d-MKO4t(iX<<Z;!Z!toJ;z;EHN=XOR(V8<2JnB0^z8L@~IzG3N z>G)L3gY<zn#Y2Y*b%Y_cAe?FVLlE8+44_~=yir%LuubBU^$iH`9RP%x?n-Vk6}%NP zcMgEo9v(Ua>|#He!w|;Fp?XY~a<PTy+`Ph6DQ;9Qa<;mrn7K}kg}outmlD8X=*#6v z(XoZi0EU`kWx<Rv%X$F81_&TE(8LsA9?;8K&P|S4i4UDXmj^lIPJQ<jpcT~gWw?cC zmZA2F?&RjaO7L&$0Akxr<yVZ__^2-;9WBk|6GR|#$W$IKlRPcZ_xj5xZCYl?aej;7 z$$s&bM?QdKo`q1KP{K*snuscx!Hm!+R=UrZ+)~AC_>oINns|b10Kzw&Kh|%eN&b<W z)v)l0Lw0iy4*fED^D@#T5)4b{nSIx2k`Kx^$df;CvCS}yKF(;A68i%8Xq(kbQ?QS> ziL-@qNbT4S>P2k{D-1=L=DW!`nZQGQ%GwTYVo+7abkR#q!7>xD$ik;F!hd;6fVT#2 b;3u>qRjE!lxug$XMKJrL$8D;P_+R@UX<7IA diff --git a/pype/resources/icons/pype_splash_dev.png b/pype/resources/icons/pype_splash_dev.png index b452eb28120438711058702fd87e4c26a7cb7f62..2ac49abb9d65f6e13beda7203f459754470a6728 100644 GIT binary patch literal 84102 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 (n;b$kWZ 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 literal 6890 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 diff --git a/pype/resources/icons/workfiles.png b/pype/resources/icons/workfiles.png index f17c869600c4deff23b1a556b54676a9b2943413..8541a6d68c577b9a92fe52de32436394522f5273 100644 GIT binary patch literal 70900 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 VB0!Lcn=RlLkT;r2RSH%g{||>7>t6r> literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X*aCb)Tz}4y`Tzg_%-XM3KoO>rAiv=M3{STkcma9-o-U3d z6}PTjHsk}De&E~x`DG#^T+J76O!ejvIG|*~EO3O$p+n|C^U{wZh6YYdf7mX?-ev!C w{XRo=gJuHj1(vHK{$`$m_FrdfIX5seOnb>BSjqC?1kh*(Pgg&ebxsLQ00S>Xn*aa+ From 351a8c030ce0c6aa1cc1d27ca1ada2a0b7f95441 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 13:24:46 +0200 Subject: [PATCH 220/295] ignore test file --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 47a37410e6..3d6e919d5a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ Network Trash Folder Temporary Items .apdisk + # CX_Freeze ########### /build @@ -79,4 +80,5 @@ pype/premiere/ppro/js/debug.log # VScode files .vscode/ .env -dump.sql \ No newline at end of file +dump.sql +test_localsystem.txt \ No newline at end of file From 1def79a6ae502ed41c64ced88bcd13c5d2a1603b Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 13:25:02 +0200 Subject: [PATCH 221/295] Nuke: menu name from environment --- pype/hosts/nuke/api/menu.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index d638034809..8e3cbebbaa 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -1,3 +1,4 @@ +import os import nuke from avalon.api import Session @@ -10,7 +11,7 @@ log = Logger().get_logger(__name__) def install(): menubar = nuke.menu("Nuke") - menu = menubar.findItem(Session["AVALON_LABEL"]) + menu = menubar.findItem(os.environ["AVALON_LABEL"]) # replace reset resolution from avalon core to pype's name = "Work Files..." @@ -90,7 +91,7 @@ def install(): def uninstall(): menubar = nuke.menu("Nuke") - menu = menubar.findItem(Session["AVALON_LABEL"]) + menu = menubar.findItem(os.environ["AVALON_LABEL"]) for item in menu.items(): log.info("Removing menu item: {}".format(item.name())) From 150c51cee04756452477fe372fcaae4f90ff2aff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 13:45:46 +0200 Subject: [PATCH 222/295] change Pype to OpenPype in avalon localization file --- pype/hosts/tvpaint/resources/avalon.loc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/tvpaint/resources/avalon.loc b/pype/hosts/tvpaint/resources/avalon.loc index cda27162e6..3cfb7e9db4 100644 --- a/pype/hosts/tvpaint/resources/avalon.loc +++ b/pype/hosts/tvpaint/resources/avalon.loc @@ -10,7 +10,7 @@ #------------ COMMON ----------------------------- #------------------------------------------------- -$100 "Pype Tools" +$100 "OpenPype Tools" $10010 "Workfiles" $10020 "Load" From 47da236e3ed202ad9d48624e61bdcf597dda9af2 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 13:46:43 +0200 Subject: [PATCH 223/295] fix loader template schemas --- .../defaults/project_anatomy/attributes.json | 14 +++++++- .../defaults/project_settings/global.json | 14 ++++---- .../defaults/project_settings/maya.json | 33 ------------------- .../schemas/schema_maya_load.json | 26 --------------- .../schemas/schema_nuke_load.json | 2 +- ....json => template_loader_plugin_nuke.json} | 0 6 files changed, 21 insertions(+), 68 deletions(-) rename pype/settings/entities/schemas/projects_schema/schemas/{template_loader_plugin.json => template_loader_plugin_nuke.json} (100%) diff --git a/pype/settings/defaults/project_anatomy/attributes.json b/pype/settings/defaults/project_anatomy/attributes.json index 1d16be42c5..987021f25b 100644 --- a/pype/settings/defaults/project_anatomy/attributes.json +++ b/pype/settings/defaults/project_anatomy/attributes.json @@ -9,6 +9,18 @@ "resolutionWidth": 1920, "resolutionHeight": 1080, "pixelAspect": 1.0, - "applications": [], + "applications": [ + "maya_2020", + "nuke_12-2", + "nukex_12-2", + "hiero_12-2", + "resolve_16", + "houdini_18-5", + "blender_2-90", + "harmony_20", + "photoshop_2021", + "aftereffects_2021", + "unreal_4-24" + ], "tools_env": [] } \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index c8eea42134..8081f92ef7 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -1,10 +1,4 @@ { - "project_plugins": { - "windows": [], - "darwin": [], - "linux": [] - }, - "project_environments": {}, "publish": { "IntegrateHeroVersion": { "enabled": true @@ -220,5 +214,11 @@ } } } - } + }, + "project_plugins": { + "windows": [], + "darwin": [], + "linux": [] + }, + "project_environments": {} } \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/maya.json b/pype/settings/defaults/project_settings/maya.json index 6945bb0581..feddd2860a 100644 --- a/pype/settings/defaults/project_settings/maya.json +++ b/pype/settings/defaults/project_settings/maya.json @@ -459,39 +459,6 @@ 0.8, 0.5 ] - }, - "ReferenceLoader": { - "enabled": true, - "representations": [ - "ma", - "mb", - "abc", - "fbx" - ] - }, - "AudioLoader": { - "enabled": true, - "representations": [ - "wav" - ] - }, - "GpuCacheLoader": { - "enabled": true, - "representations": [ - "abc" - ] - }, - "ImagePlaneLoader": { - "enabled": true, - "representations": [ - "jpg", - "png", - "mov" - ] - }, - "MatchmoveLoader": { - "enabled": true, - "representations": [] } }, "workfile_build": { diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json index 3615c1477c..dd9d0508b4 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json @@ -151,32 +151,6 @@ ] } ] - }, - { - "type": "schema_template", - "name": "template_loader_plugin", - "template_data": [ - { - "key": "ReferenceLoader", - "label": "Reference Loader" - }, - { - "key": "AudioLoader", - "label": "Audio Loader" - }, - { - "key": "GpuCacheLoader", - "label": "GpuCache Loader" - }, - { - "key": "ImagePlaneLoader", - "label": "Imageplane Loader" - }, - { - "key": "MatchmoveLoader", - "label": "Matchmove Loader" - } - ] } ] } diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_load.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_load.json index 9d132e33b4..737843ad98 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_load.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_load.json @@ -6,7 +6,7 @@ "children": [ { "type": "schema_template", - "name": "template_loader_plugin", + "name": "template_loader_plugin_nuke", "template_data": [ { "key": "LoadImage", diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin_nuke.json similarity index 100% rename from pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json rename to pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin_nuke.json From abdf4a1f99d566bca8183aae907f1b60d09a95ae Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 14:10:43 +0200 Subject: [PATCH 224/295] changed environments in start.py --- start.py | 64 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/start.py b/start.py index 8d60a14403..ba46d539ca 100644 --- a/start.py +++ b/start.py @@ -281,7 +281,7 @@ def _process_arguments() -> tuple: def _determine_mongodb() -> str: """Determine mongodb connection string. - First use ``PYPE_MONGO`` environment variable, then system keyring. + First use ``OPENPYPE_MONGO`` environment variable, then system keyring. Then try to run **Igniter UI** to let user specify it. Returns: @@ -292,7 +292,7 @@ def _determine_mongodb() -> str: """ - pype_mongo = os.getenv("PYPE_MONGO", None) + pype_mongo = os.getenv("OPENPYPE_MONGO", None) if not pype_mongo: # try system keyring try: @@ -313,23 +313,23 @@ def _determine_mongodb() -> str: def _initialize_environment(pype_version: PypeVersion) -> None: version_path = pype_version.path - os.environ["PYPE_VERSION"] = pype_version.version + os.environ["OPENPYPE_VERSION"] = pype_version.version # set PYPE_ROOT to point to currently used Pype version. - os.environ["PYPE_ROOT"] = os.path.normpath(version_path.as_posix()) + os.environ["OPENPYPE_ROOT"] = os.path.normpath(version_path.as_posix()) # inject version to Python environment (sys.path, ...) print(">>> Injecting Pype version to running environment ...") bootstrap.add_paths_from_directory(version_path) - # Additional sys paths related to PYPE_ROOT directory - # TODO move additional paths to `boot` part when PYPE_ROOT will point + # Additional sys paths related to OPENPYPE_ROOT directory + # TODO move additional paths to `boot` part when OPENPYPE_ROOT will point # to same hierarchy from code and from frozen pype additional_paths = [ # add pype tools - os.path.join(os.environ["PYPE_ROOT"], "pype", "pype", "tools"), + os.path.join(os.environ["OPENPYPE_ROOT"], "pype", "pype", "tools"), # add common pype vendor # (common for multiple Python interpreter versions) os.path.join( - os.environ["PYPE_ROOT"], + os.environ["OPENPYPE_ROOT"], "pype", "pype", "vendor", @@ -338,7 +338,7 @@ def _initialize_environment(pype_version: PypeVersion) -> None: ) ] - split_paths = os.getenv("PYTHONPATH", "").split(os.pathsep) + split_paths = os.getenv("OPENPYTHONPATH", "").split(os.pathsep) for path in additional_paths: split_paths.insert(0, path) sys.path.insert(0, path) @@ -351,7 +351,7 @@ def _find_frozen_pype(use_version: str = None, """Find Pype to run from frozen code. This will process and modify environment variables: - ``PYTHONPATH``, ``PYPE_VERSION``, ``PYPE_ROOT`` + ``PYTHONPATH``, ``OPENPYPE_VERSION``, ``OPENPYPE_ROOT`` Args: use_version (str, optional): Try to use specified version. @@ -368,7 +368,7 @@ def _find_frozen_pype(use_version: str = None, pype_version = None pype_versions = bootstrap.find_pype(include_zips=True, staging=use_staging) - if not os.getenv("PYPE_TRYOUT"): + if not os.getenv("OPENPYPE_TRYOUT"): try: # use latest one found (last in the list is latest) pype_version = pype_versions[-1] @@ -399,7 +399,7 @@ def _find_frozen_pype(use_version: str = None, if not pype_versions: # no Pype versions found anyway, lets use then the one # shipped with frozen Pype - if not os.getenv("PYPE_TRYOUT"): + if not os.getenv("OPENPYPE_TRYOUT"): print("*** Still no luck finding Pype.") print(("*** We'll try to use the one coming " "with Pype installation.")) @@ -476,7 +476,7 @@ def _bootstrap_from_code(use_version): # get current version of Pype local_version = bootstrap.get_local_live_version() - os.environ["PYPE_VERSION"] = local_version + os.environ["OPENPYPE_VERSION"] = local_version if use_version and use_version != local_version: pype_versions = bootstrap.find_pype(include_zips=True) version_path = BootstrapRepos.get_version_path_from_list( @@ -484,10 +484,10 @@ def _bootstrap_from_code(use_version): if version_path: # use specified bootstrap.add_paths_from_directory(version_path) - os.environ["PYPE_VERSION"] = use_version + os.environ["OPENPYPE_VERSION"] = use_version else: version_path = pype_root - os.environ["PYPE_ROOT"] = pype_root + os.environ["OPENPYPE_ROOT"] = pype_root repos = os.listdir(os.path.join(pype_root, "repos")) repos = [os.path.join(pype_root, "repos", repo) for repo in repos] # add self to python paths @@ -505,15 +505,19 @@ def _bootstrap_from_code(use_version): # in case when we are running without any version installed. if not getattr(sys, 'frozen', False): split_paths.append(site.getsitepackages()[-1]) - # TODO move additional paths to `boot` part when PYPE_ROOT will point - # to same hierarchy from code and from frozen pype + # TODO move additional paths to `boot` part when OPENPYPE_ROOT will + # point to same hierarchy from code and from frozen pype additional_paths = [ # add pype tools - os.path.join(os.environ["PYPE_ROOT"], "pype", "tools"), + os.path.join(os.environ["OPENPYPE_ROOT"], "pype", "tools"), # add common pype vendor # (common for multiple Python interpreter versions) os.path.join( - os.environ["PYPE_ROOT"], "pype", "vendor", "python", "common" + os.environ["OPENPYPE_ROOT"], + "pype", + "vendor", + "python", + "common" ) ] for path in additional_paths: @@ -555,7 +559,7 @@ def boot(): print(f"!!! {e}") sys.exit(1) - os.environ["PYPE_MONGO"] = pype_mongo + os.environ["OPENPYPE_MONGO"] = pype_mongo # ------------------------------------------------------------------------ # Set environments - load Pype path from database (if set) @@ -563,15 +567,15 @@ def boot(): # set PYPE_ROOT to running location until proper version can be # determined. if getattr(sys, 'frozen', False): - os.environ["PYPE_ROOT"] = os.path.dirname(sys.executable) + os.environ["OPENPYPE_ROOT"] = os.path.dirname(sys.executable) else: - os.environ["PYPE_ROOT"] = os.path.dirname(__file__) + os.environ["OPENPYPE_ROOT"] = os.path.dirname(__file__) # Get Pype path from database and set it to environment so Pype can # find its versions there and bootstrap them. pype_path = get_pype_path_from_db(pype_mongo) - if not os.getenv("PYPE_PATH") and pype_path: - os.environ["PYPE_PATH"] = pype_path + if not os.getenv("OPENPYPE_PATH") and pype_path: + os.environ["OPENPYPE_PATH"] = pype_path # ------------------------------------------------------------------------ # Find Pype versions @@ -590,13 +594,13 @@ def boot(): # set this to point either to `python` from venv in case of live code # or to `pype` or `pype_console` in case of frozen code - os.environ["PYPE_EXECUTABLE"] = sys.executable + os.environ["OPENPYPE_EXECUTABLE"] = sys.executable if getattr(sys, 'frozen', False): - os.environ["PYPE_REPOS_ROOT"] = os.environ["PYPE_ROOT"] + os.environ["OPENPYPE_REPOS_ROOT"] = os.environ["OPENPYPE_ROOT"] else: - os.environ["PYPE_REPOS_ROOT"] = os.path.join( - os.environ["PYPE_ROOT"], "repos") + os.environ["OPENPYPE_REPOS_ROOT"] = os.path.join( + os.environ["OPENPYPE_ROOT"], "repos") # delete Pype module and it's submodules from cache so it is used from # specific version @@ -624,7 +628,7 @@ def boot(): set_modules_environments() from pype import cli - from pype.lib import terminal as t + from pype.lib import terminal as t from pype.version import __version__ assert version_path, "Version path not defined." @@ -667,7 +671,7 @@ def get_info() -> list: inf.append(("Pype variant", "staging")) else: inf.append(("Pype variant", "production")) - inf.append(("Running pype from", os.environ.get('PYPE_ROOT'))) + inf.append(("Running pype from", os.environ.get('OPENPYPE_ROOT'))) inf.append(("Using mongodb", components["host"])) if os.environ.get("FTRACK_SERVER"): From c26f3ff8c74e6c39cd771ab4ff8e1fb0ec94d7c0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 14:14:11 +0200 Subject: [PATCH 225/295] changed prefixes in igniter --- igniter/bootstrap_repos.py | 12 ++++++------ igniter/install_dialog.py | 5 ++++- igniter/install_thread.py | 10 +++++----- igniter/user_settings.py | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index 58d59afe88..ec980805be 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -625,7 +625,7 @@ class BootstrapRepos: Resolution order for Pype is following: - 1) First we test for ``PYPE_PATH`` environment variable + 1) First we test for ``OPENPYPE_PATH`` environment variable 2) We try to find ``pypePath`` in registry setting 3) We use user data directory @@ -660,9 +660,9 @@ class BootstrapRepos: if pype_path: dir_to_search = pype_path else: - if os.getenv("PYPE_PATH"): - if Path(os.getenv("PYPE_PATH")).exists(): - dir_to_search = Path(os.getenv("PYPE_PATH")) + if os.getenv("OPENPYPE_PATH"): + if Path(os.getenv("OPENPYPE_PATH")).exists(): + dir_to_search = Path(os.getenv("OPENPYPE_PATH")) else: try: registry_dir = Path( @@ -688,7 +688,7 @@ class BootstrapRepos: """Process user entered location string. It decides if location string is mongodb url or path. - If it is mongodb url, it will connect and load ``PYPE_PATH`` from + If it is mongodb url, it will connect and load ``OPENPYPE_PATH`` from there and use it as path to Pype. In it is _not_ mongodb url, it is assumed we have a path, this is tested and zip file is produced and installed using :meth:`create_version_from_live_code`. @@ -706,7 +706,7 @@ class BootstrapRepos: if location.startswith("mongodb"): pype_path = get_pype_path_from_db(location) if not pype_path: - self._print("cannot find PYPE_PATH in settings.") + self._print("cannot find OPENPYPE_PATH in settings.") return None # if not successful, consider location to be fs path. diff --git a/igniter/install_dialog.py b/igniter/install_dialog.py index 0eb518c2e3..15b9683639 100644 --- a/igniter/install_dialog.py +++ b/igniter/install_dialog.py @@ -46,7 +46,10 @@ class InstallDialog(QtWidgets.QDialog): self.mongo_url = "" try: - self.mongo_url = os.getenv("PYPE_MONGO", "") or self.registry.get_secure_item("pypeMongo") # noqa: E501 + self.mongo_url = ( + os.getenv("OPENPYPE_MONGO", "") + or self.registry.get_secure_item("pypeMongo") + ) except ValueError: pass diff --git a/igniter/install_thread.py b/igniter/install_thread.py index a184a19d36..b0da4c9f0d 100644 --- a/igniter/install_thread.py +++ b/igniter/install_thread.py @@ -68,7 +68,7 @@ class InstallThread(QThread): # user did not entered url if not self._mongo: # it not set in environment - if not os.getenv("PYPE_MONGO"): + if not os.getenv("OPENPYPE_MONGO"): # try to get it from settings registry try: self._mongo = bs.registry.get_secure_item("pypeMongo") @@ -78,12 +78,12 @@ class InstallThread(QThread): self.finished.emit(InstallResult(-1)) return else: - self._mongo = os.getenv("PYPE_MONGO") + self._mongo = os.getenv("OPENPYPE_MONGO") else: self.message.emit("Saving mongo connection string ...", False) bs.registry.set_secure_item("pypeMongo", self._mongo) - os.environ["PYPE_MONGO"] = self._mongo + os.environ["OPENPYPE_MONGO"] = self._mongo self.message.emit( f"Detecting installed Pype versions in {bs.data_dir}", False) @@ -160,7 +160,7 @@ class InstallThread(QThread): return else: # if we have mongo connection string, validate it, set it to - # user settings and get PYPE_PATH from there. + # user settings and get OPENPYPE_PATH from there. if self._mongo: if not validate_mongo_connection(self._mongo): self.message.emit( @@ -168,7 +168,7 @@ class InstallThread(QThread): self.finished.emit(InstallResult(-1)) return bs.registry.set_secure_item("pypeMongo", self._mongo) - os.environ["PYPE_MONGO"] = self._mongo + os.environ["OPENPYPE_MONGO"] = self._mongo self.message.emit(f"processing {self._path}", True) repo_file = bs.process_entered_location(self._path) diff --git a/igniter/user_settings.py b/igniter/user_settings.py index 00ce68cb0b..b0c2ac2370 100644 --- a/igniter/user_settings.py +++ b/igniter/user_settings.py @@ -211,7 +211,7 @@ class IniSettingRegistry(ASettingRegistry): # type: (str, str) -> IniSettingRegistry super(IniSettingRegistry, self).__init__(name) # get registry file - version = os.getenv("PYPE_VERSION", "N/A") + version = os.getenv("OPENPYPE_VERSION", "N/A") self._registry_file = os.path.join(path, "{}.ini".format(name)) if not os.path.exists(self._registry_file): with open(self._registry_file, mode="w") as cfg: @@ -367,7 +367,7 @@ class JSONSettingRegistry(ASettingRegistry): now = datetime.now().strftime("%d/%m/%Y %H:%M:%S") header = { "__metadata__": { - "pype-version": os.getenv("PYPE_VERSION", "N/A"), + "pype-version": os.getenv("OPENPYPE_VERSION", "N/A"), "generated": now }, "registry": {} From 1106554fb6fb40abb130f24df0163fd660d54d80 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 14:17:57 +0200 Subject: [PATCH 226/295] Resolve: rebranding to OpenPype --- pype/hosts/resolve/README.markdown | 10 ++++---- pype/hosts/resolve/api/lib.py | 24 +++++++++---------- pype/hosts/resolve/api/menu.py | 8 +++---- pype/hosts/resolve/api/menu_style.qss | 2 +- pype/hosts/resolve/api/pipeline.py | 4 ++-- pype/hosts/resolve/api/plugin.py | 6 ++--- pype/hosts/resolve/api/todo-rendering.py | 2 +- pype/hosts/resolve/api/utils.py | 2 +- pype/hosts/resolve/hooks/pre_resolve_setup.py | 2 +- .../plugins/create/create_shot_clip.py | 2 +- .../plugins/publish/collect_instances.py | 2 +- ...ripts.py => OpenPype_sync_util_scripts.py} | 2 +- ..._PYPE__MENU__.py => __OpenPype__Menu__.py} | 4 ++-- .../utility_scripts/tests/test_otio_as_edl.py | 4 ++-- .../testing_create_timeline_item_from_path.py | 4 ++-- 15 files changed, 39 insertions(+), 39 deletions(-) rename pype/hosts/resolve/utility_scripts/{PYPE_sync_util_scripts.py => OpenPype_sync_util_scripts.py} (82%) rename pype/hosts/resolve/utility_scripts/{__PYPE__MENU__.py => __OpenPype__Menu__.py} (82%) diff --git a/pype/hosts/resolve/README.markdown b/pype/hosts/resolve/README.markdown index f8d2da0794..50664fbd21 100644 --- a/pype/hosts/resolve/README.markdown +++ b/pype/hosts/resolve/README.markdown @@ -1,7 +1,7 @@ #### Basic setup - Install [latest DaVinci Resolve](https://sw.blackmagicdesign.com/DaVinciResolve/v16.2.8/DaVinci_Resolve_Studio_16.2.8_Windows.zip?Key-Pair-Id=APKAJTKA3ZJMJRQITVEA&Signature=EcFuwQFKHZIBu2zDj5LTCQaQDXcKOjhZY7Fs07WGw24xdDqfwuALOyKu+EVzDX2Tik0cWDunYyV0r7hzp+mHmczp9XP4YaQXHdyhD/2BGWDgiMsiTQbNkBgbfy5MsAMFY8FHCl724Rxm8ke1foWeUVyt/Cdkil+ay+9sL72yFhaSV16sncko1jCIlCZeMkHhbzqPwyRuqLGmxmp8ey9KgBhI3wGFFPN201VMaV+RHrpX+KAfaR6p6dwo3FrPbRHK9TvMI1RA/1lJ3fVtrkDW69LImIKAWmIxgcStUxR9/taqLOD66FNiflHd1tufHv3FBa9iYQsjb3VLMPx7OCwLyg==&Expires=1608308139) -- add absolute path to ffmpeg into pype settings +- add absolute path to ffmpeg into openpype settings ![image](https://user-images.githubusercontent.com/40640033/102630786-43294f00-414d-11eb-98de-f0ae51f62077.png) - install Python 3.6 into `%LOCALAPPDATA%/Programs/Python/Python36` (only respected path by Resolve) - install OpenTimelineIO for 3.6 `%LOCALAPPDATA%\Programs\Python\Python36\python.exe -m pip install git+https://github.com/PixarAnimationStudios/OpenTimelineIO.git@5aa24fbe89d615448876948fe4b4900455c9a3e8` and move builded files from `%LOCALAPPDATA%/Programs/Python/Python36/Lib/site-packages/opentimelineio/cxx-libs/bin and lib` to `%LOCALAPPDATA%/Programs/Python/Python36/Lib/site-packages/opentimelineio/`. I was building it on Win10 machine with Visual Studio Community 2019 and @@ -16,11 +16,11 @@ This is how it looks on my testing project timeline ![image](https://user-images.githubusercontent.com/40640033/102637638-96ec6600-4156-11eb-9656-6e8e3ce4baf8.png) Notice I had renamed tracks to `main` (holding metadata markers) and `review` used for generating review data with ffmpeg confersion to jpg sequence. -1. you need to start Pype menu from Resolve/EditTab/Menu/Workspace/Scripts/**PYPE_MENU** +1. you need to start OpenPype menu from Resolve/EditTab/Menu/Workspace/Scripts/**__OpenPype_Menu__** 2. then select any clips in `main` track and change their color to `Chocolate` -3. in Pype Menu select `Create` +3. in OpenPype Menu select `Create` 4. in Creator select `Create Publishable Clip [New]` (temporary name) 5. set `Rename clips` to True, Master Track to `main` and Use review track to `review` as in picture ![image](https://user-images.githubusercontent.com/40640033/102643773-0d419600-4160-11eb-919e-9c2be0aecab8.png) -6. after you hit `ok` all clips are colored to `ping` and marked with pype metadata tag -7. git `Publish` on pype menu and see that all had been collected correctly. That is the last step for now as rest is Work in progress. Next steps will follow. +6. after you hit `ok` all clips are colored to `ping` and marked with openpype metadata tag +7. git `Publish` on openpype menu and see that all had been collected correctly. That is the last step for now as rest is Work in progress. Next steps will follow. diff --git a/pype/hosts/resolve/api/lib.py b/pype/hosts/resolve/api/lib.py index 11bf8a3217..5c204bf709 100644 --- a/pype/hosts/resolve/api/lib.py +++ b/pype/hosts/resolve/api/lib.py @@ -16,24 +16,24 @@ self = sys.modules[__name__] self.project_manager = None self.media_storage = None -# Pype sequencial rename variables +# OpenPype sequencial rename variables self.rename_index = 0 self.rename_add = 0 self.publish_clip_color = "Pink" self.pype_marker_workflow = True -# Pype compound clip workflow variable +# OpenPype compound clip workflow variable self.pype_tag_name = "VFX Notes" -# Pype marker workflow variables -self.pype_marker_name = "PYPEDATA" +# OpenPype marker workflow variables +self.pype_marker_name = "OpenPypeData" self.pype_marker_duration = 1 self.pype_marker_color = "Mint" self.temp_marker_frame = None -# Pype default timeline -self.pype_timeline_name = "PypeTimeline" +# OpenPype default timeline +self.pype_timeline_name = "OpenPypeTimeline" @contextlib.contextmanager @@ -360,13 +360,13 @@ def get_pype_timeline_item_by_name(name: str) -> object: def get_timeline_item_pype_tag(timeline_item): """ - Get pype track item tag created by creator or loader plugin. + Get openpype track item tag created by creator or loader plugin. Attributes: trackItem (resolve.TimelineItem): resolve object Returns: - dict: pype tag data + dict: openpype tag data """ return_tag = None @@ -389,7 +389,7 @@ def get_timeline_item_pype_tag(timeline_item): def set_timeline_item_pype_tag(timeline_item, data=None): """ - Set pype track item tag to input timeline_item. + Set openpype track item tag to input timeline_item. Attributes: trackItem (resolve.TimelineItem): resolve api object @@ -399,7 +399,7 @@ def set_timeline_item_pype_tag(timeline_item, data=None): """ data = data or dict() - # get available pype tag if any + # get available openpype tag if any tag_data = get_timeline_item_pype_tag(timeline_item) if self.pype_marker_workflow: @@ -418,7 +418,7 @@ def set_timeline_item_pype_tag(timeline_item, data=None): self.pype_tag_name, json.dumps(tag_data)) else: tag_data = data - # if pype tag available then update with input data + # if openpype tag available then update with input data # add it to the input track item timeline_item.SetMetadata(self.pype_tag_name, json.dumps(tag_data)) @@ -672,7 +672,7 @@ def _validate_tc(x): def get_pype_clip_metadata(clip): """ - Get pype metadata created by creator plugin + Get openpype metadata created by creator plugin Attributes: clip (resolve.TimelineItem): resolve's object diff --git a/pype/hosts/resolve/api/menu.py b/pype/hosts/resolve/api/menu.py index 73ea937513..68ba3af967 100644 --- a/pype/hosts/resolve/api/menu.py +++ b/pype/hosts/resolve/api/menu.py @@ -44,11 +44,11 @@ class Spacer(QtWidgets.QWidget): self.setLayout(layout) -class PypeMenu(QtWidgets.QWidget): +class OpenPypeMenu(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(self.__class__, self).__init__(*args, **kwargs) - self.setObjectName("PypeMenu") + self.setObjectName("OpenPypeMenu") self.setWindowFlags( QtCore.Qt.Window @@ -58,7 +58,7 @@ class PypeMenu(QtWidgets.QWidget): | QtCore.Qt.WindowStaysOnTopHint ) - self.setWindowTitle("Pype") + self.setWindowTitle("OpenPype") workfiles_btn = QtWidgets.QPushButton("Workfiles", self) create_btn = QtWidgets.QPushButton("Create", self) publish_btn = QtWidgets.QPushButton("Publish", self) @@ -144,7 +144,7 @@ class PypeMenu(QtWidgets.QWidget): def launch_pype_menu(): app = QtWidgets.QApplication(sys.argv) - pype_menu = PypeMenu() + pype_menu = OpenPypeMenu() stylesheet = load_stylesheet() pype_menu.setStyleSheet(stylesheet) diff --git a/pype/hosts/resolve/api/menu_style.qss b/pype/hosts/resolve/api/menu_style.qss index 5a1d39fe79..fd947e58c1 100644 --- a/pype/hosts/resolve/api/menu_style.qss +++ b/pype/hosts/resolve/api/menu_style.qss @@ -51,7 +51,7 @@ QLineEdit { qproperty-alignment: AlignCenter; } -#PypeMenu { +#OpenPypeMenu { border: 1px solid #fef9ef; } diff --git a/pype/hosts/resolve/api/pipeline.py b/pype/hosts/resolve/api/pipeline.py index 2d08203650..7666ac670b 100644 --- a/pype/hosts/resolve/api/pipeline.py +++ b/pype/hosts/resolve/api/pipeline.py @@ -150,7 +150,7 @@ def ls(): def parse_container(timeline_item, validate=True): - """Return container data from timeline_item's pype tag. + """Return container data from timeline_item's openpype tag. Args: timeline_item (hiero.core.TrackItem): A containerised track item. @@ -187,7 +187,7 @@ def parse_container(timeline_item, validate=True): def update_container(timeline_item, data=None): - """Update container data to input timeline_item's pype tag. + """Update container data to input timeline_item's openpype tag. Args: timeline_item (hiero.core.TrackItem): A containerised track item. diff --git a/pype/hosts/resolve/api/plugin.py b/pype/hosts/resolve/api/plugin.py index 0423f15c2a..1273c9f1df 100644 --- a/pype/hosts/resolve/api/plugin.py +++ b/pype/hosts/resolve/api/plugin.py @@ -25,7 +25,7 @@ class CreatorWidget(QtWidgets.QDialog): | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowStaysOnTopHint ) - self.setWindowTitle(name or "Pype Creator Input") + self.setWindowTitle(name or "OpenPype Creator Input") self.resize(500, 700) # Where inputs and labels are set @@ -527,7 +527,7 @@ class PublishClip: kwargs (optional): additional data needed for rename=True (presets) Returns: - hiero.core.TrackItem: hiero track item object with pype tag + hiero.core.TrackItem: hiero track item object with openpype tag """ vertical_clip_match = dict() tag_data = dict() @@ -623,7 +623,7 @@ class PublishClip: "track_data": self.timeline_item_data["track"] }) - # create pype tag on timeline_item and add data + # create openpype tag on timeline_item and add data lib.imprint(self.timeline_item, self.tag_data) return self.timeline_item diff --git a/pype/hosts/resolve/api/todo-rendering.py b/pype/hosts/resolve/api/todo-rendering.py index 87b04dd98f..5238d76dec 100644 --- a/pype/hosts/resolve/api/todo-rendering.py +++ b/pype/hosts/resolve/api/todo-rendering.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# TODO: convert this script to be usable with PYPE +# TODO: convert this script to be usable with OpenPype """ Example DaVinci Resolve script: Load a still from DRX file, apply the still to all clips in all timelines. diff --git a/pype/hosts/resolve/api/utils.py b/pype/hosts/resolve/api/utils.py index 32ac5b2aa9..25110de327 100644 --- a/pype/hosts/resolve/api/utils.py +++ b/pype/hosts/resolve/api/utils.py @@ -146,4 +146,4 @@ def setup(env=None): # synchronize resolve utility scripts _sync_utility_scripts(env) - log.info("Resolve Pype wrapper has been installed") + log.info("Resolve OpenPype wrapper has been installed") diff --git a/pype/hosts/resolve/hooks/pre_resolve_setup.py b/pype/hosts/resolve/hooks/pre_resolve_setup.py index d19c56fe09..9e003cc538 100644 --- a/pype/hosts/resolve/hooks/pre_resolve_setup.py +++ b/pype/hosts/resolve/hooks/pre_resolve_setup.py @@ -14,7 +14,7 @@ class ResolvePrelaunch(PreLaunchHook): app_groups = ["resolve"] def execute(self): - # TODO: add OTIO installation from `pype/requirements.py` + # TODO: add OTIO installation from `openpype/requirements.py` # making sure pyton 3.6 is installed at provided path py36_dir = os.path.normpath( self.launch_context.env.get("PYTHON36_RESOLVE", "")) diff --git a/pype/hosts/resolve/plugins/create/create_shot_clip.py b/pype/hosts/resolve/plugins/create/create_shot_clip.py index 09b2b73775..5b7dd66a25 100644 --- a/pype/hosts/resolve/plugins/create/create_shot_clip.py +++ b/pype/hosts/resolve/plugins/create/create_shot_clip.py @@ -12,7 +12,7 @@ class CreateShotClip(resolve.Creator): defaults = ["Main"] gui_tracks = resolve.get_video_track_names() - gui_name = "Pype publish attributes creator" + gui_name = "OpenPype publish attributes creator" gui_info = "Define sequential rename and fill hierarchy data." gui_inputs = { "renameHierarchy": { diff --git a/pype/hosts/resolve/plugins/publish/collect_instances.py b/pype/hosts/resolve/plugins/publish/collect_instances.py index b1eafd512e..2465e2e2c4 100644 --- a/pype/hosts/resolve/plugins/publish/collect_instances.py +++ b/pype/hosts/resolve/plugins/publish/collect_instances.py @@ -26,7 +26,7 @@ class CollectInstances(pyblish.api.ContextPlugin): data = dict() timeline_item = timeline_item_data["clip"]["item"] - # get pype tag data + # get openpype tag data tag_data = resolve.get_timeline_item_pype_tag(timeline_item) self.log.debug(f"__ tag_data: {pformat(tag_data)}") diff --git a/pype/hosts/resolve/utility_scripts/PYPE_sync_util_scripts.py b/pype/hosts/resolve/utility_scripts/OpenPype_sync_util_scripts.py similarity index 82% rename from pype/hosts/resolve/utility_scripts/PYPE_sync_util_scripts.py rename to pype/hosts/resolve/utility_scripts/OpenPype_sync_util_scripts.py index 753bddc1da..5b5d487c74 100644 --- a/pype/hosts/resolve/utility_scripts/PYPE_sync_util_scripts.py +++ b/pype/hosts/resolve/utility_scripts/OpenPype_sync_util_scripts.py @@ -6,7 +6,7 @@ import pype def main(env): import pype.hosts.resolve as bmdvr - # Registers pype's Global pyblish plugins + # Registers openpype's Global pyblish plugins pype.install() bmdvr.setup(env) diff --git a/pype/hosts/resolve/utility_scripts/__PYPE__MENU__.py b/pype/hosts/resolve/utility_scripts/__OpenPype__Menu__.py similarity index 82% rename from pype/hosts/resolve/utility_scripts/__PYPE__MENU__.py rename to pype/hosts/resolve/utility_scripts/__OpenPype__Menu__.py index 230a7a80f0..d49e75bf3a 100644 --- a/pype/hosts/resolve/utility_scripts/__PYPE__MENU__.py +++ b/pype/hosts/resolve/utility_scripts/__OpenPype__Menu__.py @@ -10,10 +10,10 @@ log = Logger().get_logger(__name__) def main(env): import pype.hosts.resolve as bmdvr - # Registers pype's Global pyblish plugins + # Registers openpype's Global pyblish plugins pype.install() - # activate resolve from pype + # activate resolve from openpype avalon.install(bmdvr) log.info(f"Avalon registred hosts: {avalon.registered_host()}") diff --git a/pype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py b/pype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py index f6f9454625..819bcaa0d2 100644 --- a/pype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py +++ b/pype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py @@ -14,9 +14,9 @@ class ThisTestGUI(TestGUI): def __init__(self): super(ThisTestGUI, self).__init__() - # Registers pype's Global pyblish plugins + # Registers openpype's Global pyblish plugins pype.install() - # activate resolve from pype + # activate resolve from openpype avalon.install(bmdvr) def _open_dir_button_pressed(self, event): diff --git a/pype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py b/pype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py index da1f980388..4c47242ab5 100644 --- a/pype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py +++ b/pype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py @@ -13,9 +13,9 @@ class ThisTestGUI(TestGUI): def __init__(self): super(ThisTestGUI, self).__init__() - # Registers pype's Global pyblish plugins + # Registers openpype's Global pyblish plugins pype.install() - # activate resolve from pype + # activate resolve from openpype avalon.install(bmdvr) def _open_dir_button_pressed(self, event): From 3b72dc9f5e320e566d0e3384ae57c9fa8cc684f7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 14:44:19 +0200 Subject: [PATCH 227/295] modified prefix in pype.lib --- pype/lib/__init__.py | 2 +- pype/lib/abstract_submit_deadline.py | 4 ++-- pype/lib/anatomy.py | 17 +++++++++-------- pype/lib/applications.py | 2 +- pype/lib/avalon_context.py | 2 +- pype/lib/execute.py | 4 ++-- pype/lib/import_utils.py | 2 +- pype/lib/local_settings.py | 4 ++-- pype/lib/log.py | 14 +++++++------- pype/lib/mongo.py | 4 ++-- pype/lib/plugin_tools.py | 6 +++--- pype/lib/pype_info.py | 4 ++-- pype/lib/terminal.py | 9 +++++---- 13 files changed, 38 insertions(+), 36 deletions(-) diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index f4282f7ea3..49ebd699b6 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -9,7 +9,7 @@ import site # add Python version specific vendor folder site.addsitedir( os.path.join( - os.getenv("PYPE_ROOT", ""), + os.getenv("OPENPYPE_ROOT", ""), "vendor", "python", "python_{}".format(sys.version[0]))) from .terminal import Terminal diff --git a/pype/lib/abstract_submit_deadline.py b/pype/lib/abstract_submit_deadline.py index 9862f534f1..12014ddfb5 100644 --- a/pype/lib/abstract_submit_deadline.py +++ b/pype/lib/abstract_submit_deadline.py @@ -607,7 +607,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin): """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa # add 10sec timeout before bailing out kwargs['timeout'] = 10 return requests.post(*args, **kwargs) @@ -626,7 +626,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin): """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa # add 10sec timeout before bailing out kwargs['timeout'] = 10 return requests.get(*args, **kwargs) diff --git a/pype/lib/anatomy.py b/pype/lib/anatomy.py index 4e7643dbbb..4c1a183ce0 100644 --- a/pype/lib/anatomy.py +++ b/pype/lib/anatomy.py @@ -156,7 +156,7 @@ class Anatomy: return self._roots_obj def root_environments(self): - """Return PYPE_ROOT_* environments for current project in dict.""" + """Return OPENPYPE_ROOT_* environments for current project in dict.""" return self._roots_obj.root_environments() def root_environmets_fill_data(self, template=None): @@ -181,7 +181,7 @@ class Anatomy: return self.roots_obj.all_root_paths() def set_root_environments(self): - """Set PYPE_ROOT_* environments for current project.""" + """Set OPENPYPE_ROOT_* environments for current project.""" self._roots_obj.set_root_environments() def root_names(self): @@ -320,7 +320,7 @@ class Anatomy: "<{}>" ## Output - "<PYPE_PROJECT_ROOT_NAS>/project/asset/task/animation_v001.ma" + "<OPENPYPE_PROJECT_ROOT_NAS>/project/asset/task/animation_v001.ma" Args: filepath (str): Full file path where root should be replaced. @@ -1359,7 +1359,7 @@ class Roots: anatomy Anatomy: Anatomy object created for a specific project. """ - env_prefix = "PYPE_PROJECT_ROOT" + env_prefix = "OPENPYPE_PROJECT_ROOT" roots_filename = "roots.json" def __init__(self, anatomy): @@ -1465,7 +1465,8 @@ class Roots: def root_environments(self): """Use root keys to create unique keys for environment variables. - Concatenates prefix "PYPE_ROOT" with root keys to create unique keys. + Concatenates prefix "OPENPYPE_ROOT" with root keys to create unique + keys. Returns: dict: Result is `{(str): (str)}` dicitonary where key represents @@ -1487,13 +1488,13 @@ class Roots: Result on windows platform:: { - "PYPE_ROOT_WORK": "P:/projects/work", - "PYPE_ROOT_PUBLISH": "P:/projects/publish" + "OPENPYPE_ROOT_WORK": "P:/projects/work", + "OPENPYPE_ROOT_PUBLISH": "P:/projects/publish" } Short example when multiroot is not used:: { - "PYPE_ROOT": "P:/projects" + "OPENPYPE_ROOT": "P:/projects" } """ return self._root_environments() diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 6df296db95..4ebf34597f 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -1187,7 +1187,7 @@ def _prepare_last_workfile(data, workdir): file_template = anatomy.templates["work"]["file"] workdir_data.update({ "version": 1, - "user": os.environ.get("PYPE_USERNAME") or getpass.getuser(), + "user": os.environ.get("OPENPYPE_USERNAME") or getpass.getuser(), "ext": extensions[0] }) diff --git a/pype/lib/avalon_context.py b/pype/lib/avalon_context.py index d4daf22142..393b6820fa 100644 --- a/pype/lib/avalon_context.py +++ b/pype/lib/avalon_context.py @@ -1153,7 +1153,7 @@ def get_creator_by_name(creator_name, case_sensitive=False): @with_avalon def change_timer_to_current_context(): """Called after context change to change timers""" - webserver_url = os.environ.get("PYPE_WEBSERVER_URL") + webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") if not webserver_url: log.warning("Couldn't find webserver url") return diff --git a/pype/lib/execute.py b/pype/lib/execute.py index f815d05f1b..441dcfa754 100644 --- a/pype/lib/execute.py +++ b/pype/lib/execute.py @@ -150,13 +150,13 @@ def get_pype_execute_args(*args): It is possible to pass any arguments that will be added after pype executables. """ - pype_executable = os.environ["PYPE_EXECUTABLE"] + pype_executable = os.environ["OPENPYPE_EXECUTABLE"] pype_args = [pype_executable] executable_filename = os.path.basename(pype_executable) if "python" in executable_filename.lower(): pype_args.append( - os.path.join(os.environ["PYPE_ROOT"], "start.py") + os.path.join(os.environ["OPENPYPE_ROOT"], "start.py") ) if args: diff --git a/pype/lib/import_utils.py b/pype/lib/import_utils.py index 5c832a925c..5fca0ae5f9 100644 --- a/pype/lib/import_utils.py +++ b/pype/lib/import_utils.py @@ -8,7 +8,7 @@ log = Logger().get_logger(__name__) def discover_host_vendor_module(module_name): host = os.environ["AVALON_APP"] - pype_root = os.environ["PYPE_ROOT"] + pype_root = os.environ["OPENPYPE_ROOT"] main_module = module_name.split(".")[0] module_path = os.path.join( pype_root, "hosts", host, "vendor", main_module) diff --git a/pype/lib/local_settings.py b/pype/lib/local_settings.py index aa372a52d2..a26d08a4de 100644 --- a/pype/lib/local_settings.py +++ b/pype/lib/local_settings.py @@ -213,7 +213,7 @@ class IniSettingRegistry(ASettingRegistry): # type: (str, str) -> IniSettingRegistry super(IniSettingRegistry, self).__init__(name) # get registry file - version = os.getenv("PYPE_VERSION", "N/A") + version = os.getenv("OPENPYPE_VERSION", "N/A") self._registry_file = os.path.join(path, "{}.ini".format(name)) if not os.path.exists(self._registry_file): with open(self._registry_file, mode="w") as cfg: @@ -369,7 +369,7 @@ class JSONSettingRegistry(ASettingRegistry): now = datetime.now().strftime("%d/%m/%Y %H:%M:%S") header = { "__metadata__": { - "pype-version": os.getenv("PYPE_VERSION", "N/A"), + "pype-version": os.getenv("OPENPYPE_VERSION", "N/A"), "generated": now }, "registry": {} diff --git a/pype/lib/log.py b/pype/lib/log.py index f6e95eea8a..9675637700 100644 --- a/pype/lib/log.py +++ b/pype/lib/log.py @@ -1,11 +1,11 @@ """ Logging to console and to mongo. For mongo logging, you need to set either -``PYPE_LOG_MONGO_URL`` to something like: +``OPENPYPE_LOG_MONGO_URL`` to something like: .. example:: mongo://user:password@hostname:port/database/collection?authSource=avalon -or set ``PYPE_LOG_MONGO_HOST`` and other variables. +or set ``OPENPYPE_LOG_MONGO_HOST`` and other variables. See :func:`_mongo_settings` Best place for it is in ``repos/pype-config/environments/global.json`` @@ -207,7 +207,7 @@ class PypeLogger: # Collection name under database in Mongo log_collection_name = "logs" - # PYPE_DEBUG + # OPENPYPE_DEBUG pype_debug = 0 # Data same for all record documents @@ -335,7 +335,7 @@ class PypeLogger: # like Ftrack event server has 3 other subprocesses that should # use same mongo id if use_mongo_logging: - mongo_id = os.environ.pop("PYPE_PROCESS_MONGO_ID", None) + mongo_id = os.environ.pop("OPENPYPE_PROCESS_MONGO_ID", None) if not mongo_id: # Create new object id mongo_id = ObjectId() @@ -347,11 +347,11 @@ class PypeLogger: # Store result to class definition cls.use_mongo_logging = use_mongo_logging - # Define if is in PYPE_DEBUG mode - cls.pype_debug = int(os.getenv("PYPE_DEBUG") or "0") + # Define if is in OPENPYPE_DEBUG mode + cls.pype_debug = int(os.getenv("OPENPYPE_DEBUG") or "0") # Mongo URL where logs will be stored - cls.log_mongo_url = os.environ.get("PYPE_MONGO") + cls.log_mongo_url = os.environ.get("OPENPYPE_MONGO") if not cls.log_mongo_url: cls.use_mongo_logging = False diff --git a/pype/lib/mongo.py b/pype/lib/mongo.py index 3ee43bb934..edb52a29ab 100644 --- a/pype/lib/mongo.py +++ b/pype/lib/mongo.py @@ -77,7 +77,7 @@ def compose_url(scheme=None, def get_default_components(): - mongo_url = os.environ.get("PYPE_MONGO") + mongo_url = os.environ.get("OPENPYPE_MONGO") if mongo_url is None: raise MongoEnvNotSet( "URL for Mongo logging connection is not set." @@ -139,7 +139,7 @@ class PypeMongoConnection: @staticmethod def get_default_mongo_url(): - return os.environ["PYPE_MONGO"] + return os.environ["OPENPYPE_MONGO"] @classmethod def get_mongo_client(cls, mongo_url=None): diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index 0f3a0a2838..f352f134d0 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -235,7 +235,7 @@ def oiio_supported(): Returns: (bool) """ - oiio_path = os.getenv("PYPE_OIIO_PATH", "") + oiio_path = os.getenv("OPENPYPE_OIIO_PATH", "") if not oiio_path or not os.path.exists(oiio_path): log.debug("OIIOTool is not configured or not present at {}". format(oiio_path)) @@ -269,7 +269,7 @@ def decompress(target_dir, file_url, (int(input_frame_end) > int(input_frame_start)) oiio_cmd = [] - oiio_cmd.append(os.getenv("PYPE_OIIO_PATH")) + oiio_cmd.append(os.getenv("OPENPYPE_OIIO_PATH")) oiio_cmd.append("--compression none") @@ -328,7 +328,7 @@ def should_decompress(file_url): """ if oiio_supported(): output = run_subprocess([ - os.getenv("PYPE_OIIO_PATH"), + os.getenv("OPENPYPE_OIIO_PATH"), "--info", "-v", file_url]) return "compression: \"dwaa\"" in output or \ "compression: \"dwab\"" in output diff --git a/pype/lib/pype_info.py b/pype/lib/pype_info.py index cbcc5811a0..d9e810e556 100644 --- a/pype/lib/pype_info.py +++ b/pype/lib/pype_info.py @@ -28,8 +28,8 @@ def get_pype_info(): "version": get_pype_version(), "version_type": version_type, "executable": executable_args[-1], - "pype_root": os.environ["PYPE_ROOT"], - "mongo_url": os.environ["PYPE_MONGO"] + "pype_root": os.environ["OPENPYPE_ROOT"], + "mongo_url": os.environ["OPENPYPE_MONGO"] } diff --git a/pype/lib/terminal.py b/pype/lib/terminal.py index 51b0bcebd6..9e9bfa9790 100644 --- a/pype/lib/terminal.py +++ b/pype/lib/terminal.py @@ -21,7 +21,7 @@ class Terminal: If :mod:`Colorama` is not found, it will still work, but without colors. Depends on :mod:`Colorama` - Using **PYPE_LOG_NO_COLORS** environment variable. + Using **OPENPYPE_LOG_NO_COLORS** environment variable. """ # Is Terminal initialized @@ -38,7 +38,8 @@ class Terminal: """Initialize Terminal class as object. First check if colorized output is disabled by environment variable - `PYPE_LOG_NO_COLORS` value. By default is colorized output turned on. + `OPENPYPE_LOG_NO_COLORS` value. By default is colorized output turned + on. Then tries to import python module that do the colors magic and create it's terminal object. Colorized output is not used if import of python @@ -49,7 +50,7 @@ class Terminal: from pype.lib import env_value_to_bool use_colors = env_value_to_bool( - "PYPE_LOG_NO_COLORS", default=Terminal.use_colors + "OPENPYPE_LOG_NO_COLORS", default=Terminal.use_colors ) if not use_colors: Terminal.use_colors = use_colors @@ -166,7 +167,7 @@ class Terminal: def log(message): """Return color formatted message. - If environment variable `PYPE_LOG_NO_COLORS` is set to + If environment variable `OPENPYPE_LOG_NO_COLORS` is set to whatever value, message will be formatted but not colorized. Args: From dcce50ea9ef527cd43da3a89c0789aa4a14f59f1 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 14:46:49 +0200 Subject: [PATCH 228/295] rename pype to openpype on icons --- igniter/install_dialog.py | 2 +- igniter/{pype.ico => openpype.ico} | Bin .../openpype_icon.png | Bin pype/hosts/hiero/api/lib.py | 2 +- pype/resources/__init__.py | 8 +++---- pype/resources/icons/Spine.json | 22 ------------------ pype/resources/icons/openpype_icon.png | Bin 0 -> 110945 bytes ...icon_dev.png => openpype_icon_staging.png} | Bin .../{pype_splash.png => openpype_splash.png} | Bin ...sh_dev.png => openpype_splash_staging.png} | Bin .../tools/settings/settings/style/__init__.py | 2 +- setup.py | 2 +- 12 files changed, 8 insertions(+), 30 deletions(-) rename igniter/{pype.ico => openpype.ico} (100%) rename pype/resources/icons/pype_icon.png => igniter/openpype_icon.png (100%) delete mode 100644 pype/resources/icons/Spine.json create mode 100644 pype/resources/icons/openpype_icon.png rename pype/resources/icons/{pype_icon_dev.png => openpype_icon_staging.png} (100%) rename pype/resources/icons/{pype_splash.png => openpype_splash.png} (100%) rename pype/resources/icons/{pype_splash_dev.png => openpype_splash_staging.png} (100%) diff --git a/igniter/install_dialog.py b/igniter/install_dialog.py index 0eb518c2e3..5fa676fd5b 100644 --- a/igniter/install_dialog.py +++ b/igniter/install_dialog.py @@ -52,7 +52,7 @@ class InstallDialog(QtWidgets.QDialog): self.setWindowTitle(f"Pype Igniter {__version__} - Pype installation") self._icon_path = os.path.join( - os.path.dirname(__file__), 'pype_icon.png') + os.path.dirname(__file__), 'openpype_icon.png') icon = QtGui.QIcon(self._icon_path) self.setWindowIcon(icon) self.setWindowFlags( diff --git a/igniter/pype.ico b/igniter/openpype.ico similarity index 100% rename from igniter/pype.ico rename to igniter/openpype.ico diff --git a/pype/resources/icons/pype_icon.png b/igniter/openpype_icon.png similarity index 100% rename from pype/resources/icons/pype_icon.png rename to igniter/openpype_icon.png diff --git a/pype/hosts/hiero/api/lib.py b/pype/hosts/hiero/api/lib.py index 14760a3137..0d37f2d075 100644 --- a/pype/hosts/hiero/api/lib.py +++ b/pype/hosts/hiero/api/lib.py @@ -241,7 +241,7 @@ def set_track_item_pype_tag(track_item, data=None): tag_data = { "editable": "0", "note": "Pype data holder", - "icon": "pype_icon.png", + "icon": "openpype_icon.png", "metadata": {k: v for k, v in data.items()} } # get available pype tag if any diff --git a/pype/resources/__init__.py b/pype/resources/__init__.py index 9adce2afe4..fdee38ab34 100644 --- a/pype/resources/__init__.py +++ b/pype/resources/__init__.py @@ -35,9 +35,9 @@ def pype_icon_filepath(debug=None): debug = bool(os.getenv("PYPE_DEV")) if debug: - icon_file_name = "pype_icon_dev.png" + icon_file_name = "openpype_icon_staging.png" else: - icon_file_name = "pype_icon.png" + icon_file_name = "openpype_icon.png" return get_resource("icons", icon_file_name) @@ -46,7 +46,7 @@ def pype_splash_filepath(debug=None): debug = bool(os.getenv("PYPE_DEV")) if debug: - splash_file_name = "pype_splash_dev.png" + splash_file_name = "openpype_splash_staging.png" else: - splash_file_name = "pype_splash.png" + splash_file_name = "openpype_splash.png" return get_resource("icons", splash_file_name) diff --git a/pype/resources/icons/Spine.json b/pype/resources/icons/Spine.json deleted file mode 100644 index 8c70d52b25..0000000000 --- a/pype/resources/icons/Spine.json +++ /dev/null @@ -1,22 +0,0 @@ -{"skeleton":{"images":""}, -"bones":[{"name":"root"}], -"slots":[ - {"name":"workfiles","bone":"root","attachment":"workfiles"}, - {"name":"circle_green","bone":"root","attachment":"circle_green"}, - {"name":"circle_red","bone":"root","attachment":"circle_red"}, - {"name":"lookmanager","bone":"root","attachment":"lookmanager"}, - {"name":"inventory","bone":"root","attachment":"inventory"}, - {"name":"loader","bone":"root","attachment":"loader"} -], -"skins":{ - "default":{ - "workfiles":{"workfiles":{"x":3877,"y":1247,"width":500,"height":500}}, - "circle_green":{"circle_green":{"x":3877,"y":280,"width":500,"height":500}}, - "circle_red":{"circle_red":{"x":5748,"y":280,"width":500,"height":500}}, - "lookmanager":{"lookmanager":{"x":5631,"y":1253,"width":500,"height":500}}, - "inventory":{"inventory":{"x":6335,"y":1265,"width":500,"height":500}}, - "loader":{"loader":{"x":4827,"y":1247,"width":500,"height":500}} - } -}, -"animations":{"animation":{}} -} \ No newline at end of file diff --git a/pype/resources/icons/openpype_icon.png b/pype/resources/icons/openpype_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c3ab1d30025adafc1c7684c249540dac6a80782c GIT binary patch literal 110945 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 $@U*l;|{0vayb_2~VYwh)n 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�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 literal 0 HcmV?d00001 diff --git a/pype/resources/icons/pype_icon_dev.png b/pype/resources/icons/openpype_icon_staging.png similarity index 100% rename from pype/resources/icons/pype_icon_dev.png rename to pype/resources/icons/openpype_icon_staging.png diff --git a/pype/resources/icons/pype_splash.png b/pype/resources/icons/openpype_splash.png similarity index 100% rename from pype/resources/icons/pype_splash.png rename to pype/resources/icons/openpype_splash.png diff --git a/pype/resources/icons/pype_splash_dev.png b/pype/resources/icons/openpype_splash_staging.png similarity index 100% rename from pype/resources/icons/pype_splash_dev.png rename to pype/resources/icons/openpype_splash_staging.png diff --git a/pype/tools/settings/settings/style/__init__.py b/pype/tools/settings/settings/style/__init__.py index a8f202d97b..9bb5e851b4 100644 --- a/pype/tools/settings/settings/style/__init__.py +++ b/pype/tools/settings/settings/style/__init__.py @@ -9,4 +9,4 @@ def load_stylesheet(): def app_icon_path(): - return os.path.join(os.path.dirname(__file__), "pype_icon.png") + return os.path.join(os.path.dirname(__file__), "openpype_icon.png") diff --git a/setup.py b/setup.py index e3be48d6e0..65956485d5 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ build_options = dict( optimize=0 ) -icon_path = pype_root / "igniter" / "pype.ico" +icon_path = pype_root / "igniter" / "openpype.ico" executables = [ Executable("start.py", base=None, From 3e0b5d4872cfc0d048a585daeb64c7e4283ae8f1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 14:54:26 +0200 Subject: [PATCH 229/295] removed publish_deadline script --- pype/scripts/publish_deadline.py | 38 -------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 pype/scripts/publish_deadline.py diff --git a/pype/scripts/publish_deadline.py b/pype/scripts/publish_deadline.py deleted file mode 100644 index 16d097a1ea..0000000000 --- a/pype/scripts/publish_deadline.py +++ /dev/null @@ -1,38 +0,0 @@ -import os -import subprocess -import platform -import argparse - - -def __main__(): - parser = argparse.ArgumentParser() - parser.add_argument("--paths", - nargs="*", - default=[], - help="The filepaths to publish. This can be a " - "directory or a path to a .json publish " - "configuration.") - - kwargs, args = parser.parse_known_args() - pype_root = os.environ.get("PYPE_SETUP_PATH") - if not pype_root: - raise Exception("PYPE_SETUP_PATH is not set") - - # TODO: set correct path - pype_command = "pype.ps1" - if platform.system().lower() == "linux": - pype_command = "pype" - - args = [os.path.join(pype_root, pype_command), - "--node", "--publish", "--paths", kwargs.paths] - - # if we are using windows, run powershell command directly to support - # UNC paths. - if platform.system().lower() == "windows": - args = ["powershell", "-NoProfile", "-noexit", "-nologo", - "-executionPolicy bypass", "-command", - '"{}; exit $LASTEXITCODE"'.format(" ".join(args))] - - print('>>> running pype ...') - p = subprocess.call(args, shell=True) - print('<<< done [ {} ]'.format(p.returncode)) From c83a6fdec8a84aebb688bfa3ddb957c2f41cae07 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 14:56:36 +0200 Subject: [PATCH 230/295] Added comment to export maya ass job --- pype/scripts/export_maya_ass_job.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pype/scripts/export_maya_ass_job.py b/pype/scripts/export_maya_ass_job.py index d343eec131..8d90fa00e5 100644 --- a/pype/scripts/export_maya_ass_job.py +++ b/pype/scripts/export_maya_ass_job.py @@ -1,4 +1,8 @@ -"""This module is used for command line exporting of ASS files.""" +"""This module is used for command line exporting of ASS files. + +WARNING: +This need to be rewriten to be able use it in Pype 3! +""" import os import argparse From 69cafcddda9904b817092d006f70edc097e6a19c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel <ondrej.samohel@pype.club> Date: Thu, 1 Apr 2021 15:02:44 +0200 Subject: [PATCH 231/295] pype -> openpype in tools and scripts --- .gitignore | 2 +- poetry.lock | 4 +-- poetry.toml | 2 +- pyproject.toml | 22 +++++++------- setup.cfg | 2 +- setup.py | 20 ++++++------- start.py | 60 ++++++++++++++++++------------------- tools/build.ps1 | 60 ++++++++++++++++++------------------- tools/build.sh | 35 +++++++++++----------- tools/build_dependencies.py | 4 +-- tools/create_env.ps1 | 41 ++++++++++++------------- tools/create_env.sh | 26 ++++++++-------- tools/create_zip.ps1 | 36 +++++++++++----------- tools/create_zip.sh | 27 +++++++++-------- tools/make_docs.ps1 | 28 ++++++++--------- tools/make_docs.sh | 27 ++++++++--------- tools/run_mongo.ps1 | 17 +++++------ tools/run_mongo.sh | 19 ++++++------ tools/run_settings.ps1 | 10 +++---- tools/run_settings.sh | 23 +++++++------- tools/run_tests.ps1 | 45 +++++++++++++--------------- tools/run_tests.sh | 29 +++++++++--------- tools/run_tray.ps1 | 8 ++--- tools/run_tray.sh | 25 ++++++++-------- tools/update_submodules.ps1 | 24 ++++++--------- tools/update_submodules.sh | 14 ++++----- 26 files changed, 289 insertions(+), 321 deletions(-) diff --git a/.gitignore b/.gitignore index 47a37410e6..5dbefa2309 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,7 @@ coverage.xml node_modules/ package-lock.json -pype/premiere/ppro/js/debug.log +openpype/premiere/ppro/js/debug.log # IDEA diff --git a/poetry.lock b/poetry.lock index e6c08b8ae9..6695a7bcca 100644 --- a/poetry.lock +++ b/poetry.lock @@ -637,8 +637,8 @@ view = ["PySide2 (>=5.11,<6.0)"] [package.source] type = "legacy" -url = "https://d.r1.wbsprt.com/pype.club/distribute" -reference = "pype" +url = "https://distribute.openpype.io/wheels" +reference = "openpype" [[package]] name = "packaging" diff --git a/poetry.toml b/poetry.toml index f05df6491a..19eca443f8 100644 --- a/poetry.toml +++ b/poetry.toml @@ -2,4 +2,4 @@ in-project = true [repositories.pype] -url = "http://d.r1.wbsprt.com/pype.club/distribute/" +url = "https://distribute.openpype.io/wheels/" diff --git a/pyproject.toml b/pyproject.toml index b6ca6574c4..ec2d9c7e3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] -name = "Pype" +name = "OpenPype" version = "3.0.0-alpha1" description = "Multi-platform open-source pipeline built around the Avalon platform, expanding it with extra features and integrations." -authors = ["Pype Club <info@pype.club>"] +authors = ["OpenPype Team <info@openpype.io>"] license = "MIT License" -homepage = "https://pype.club" -documentation = "https://pype.club/docs/artist_getting_started" -repository = "https://github.com/pypeclub/pype" +homepage = "https://openpype.io" +documentation = "https://openpype.io/docs/artist_getting_started" +repository = "https://github.com/pypeclub/openpype" readme = "README.md" keywords = ["Pipeline", "Avalon", "VFX", "animation", "automation", "tracking", "asset management"] @@ -15,9 +15,9 @@ python = "3.7.*" aiohttp = "^3.7" aiohttp_json_rpc = "*" # TVPaint server acre = { git = "https://github.com/pypeclub/acre.git" } -opentimelineio = { version = "0.14.0.dev1", source = "pype" } +opentimelineio = { version = "0.14.0.dev1", source = "openpype" } appdirs = "^1.4.3" -blessed = "^1.17" # pype terminal formatting +blessed = "^1.17" # openpype terminal formatting clique = "1.5.*" Click = "^7" dnspython = "^2.1.0" @@ -65,12 +65,12 @@ tqdm = "*" wheel = "*" [tool.poetry.urls] -"Bug Tracker" = "https://github.com/pypeclub/pype/issues" -"Discussions" = "https://github.com/pypeclub/pype/discussions" +"Bug Tracker" = "https://github.com/pypeclub/openpype/issues" +"Discussions" = "https://github.com/pypeclub/openpype/discussions" [[tool.poetry.source]] -name = "pype" -url = "https://d.r1.wbsprt.com/pype.club/distribute/" +name = "openpype" +url = "https://distribute.openpype.io/wheels/" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/setup.cfg b/setup.cfg index bc66f0c4d5..03c999e05f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,4 +25,4 @@ omit = /tests directory = ./coverage [tool:pytest] -norecursedirs = repos/* pype/modules/ftrack/* \ No newline at end of file +norecursedirs = repos/* openpype/modules/ftrack/* \ No newline at end of file diff --git a/setup.py b/setup.py index e3be48d6e0..1c98935000 100644 --- a/setup.py +++ b/setup.py @@ -10,9 +10,9 @@ from sphinx.setup_command import BuildDoc version = {} -pype_root = Path(os.path.dirname(__file__)) +openpype_root = Path(os.path.dirname(__file__)) -with open(pype_root / "pype" / "version.py") as fp: +with open(openpype_root / "pype" / "version.py") as fp: exec(fp.read(), version) version_match = re.search(r"(\d+\.\d+.\d+).*", version["__version__"]) @@ -53,7 +53,7 @@ excludes = [] bin_includes = [] include_files = [ "igniter", - "pype", + "openpype", "repos", "schema", "vendor", @@ -78,28 +78,28 @@ build_options = dict( optimize=0 ) -icon_path = pype_root / "igniter" / "pype.ico" +icon_path = openpype_root / "igniter" / "pype.ico" executables = [ Executable("start.py", base=None, - target_name="pype_console", icon=icon_path.as_posix()), + target_name="openpype_console", icon=icon_path.as_posix()), Executable("start.py", base=base, - target_name="pype_gui", icon=icon_path.as_posix()) + target_name="openpype_gui", icon=icon_path.as_posix()) ] setup( - name="pype", + name="OpenPype", version=__version__, description="Ultimate pipeline", cmdclass={"build_sphinx": BuildDoc}, options={ "build_exe": build_options, "build_sphinx": { - "project": "Pype", + "project": "OpenPype", "version": __version__, "release": __version__, - "source_dir": (pype_root / "docs" / "source").as_posix(), - "build_dir": (pype_root / "docs" / "build").as_posix() + "source_dir": (openpype_root / "docs" / "source").as_posix(), + "build_dir": (openpype_root / "docs" / "build").as_posix() } }, executables=executables diff --git a/start.py b/start.py index 8d60a14403..dd9e81a698 100644 --- a/start.py +++ b/start.py @@ -1,46 +1,46 @@ # -*- coding: utf-8 -*- -"""Main entry point for Pype command. +"""Main entry point for OpenPype command. -Bootstrapping process of Pype is as follows: +Bootstrapping process of OpenPype is as follows: -`PYPE_PATH` is checked for existence - either one from environment or +`OPENPYPE_PATH` is checked for existence - either one from environment or from user settings. Precedence takes the one set by environment. -On this path we try to find pype in directories version string in their names. -For example: `pype-v3.0.1-foo` is valid name, or even `foo_3.0.2` - as long -as version can be determined from its name _AND_ file `pype/pype/version.py` -can be found inside, it is considered Pype installation. +On this path we try to find OpenPype in directories version string in their names. +For example: `openpype-v3.0.1-foo` is valid name, or even `foo_3.0.2` - as long +as version can be determined from its name _AND_ file `openpype/openpype/version.py` +can be found inside, it is considered OpenPype installation. -If no Pype repositories are found in `PYPE_PATH` (user data dir) -then **Igniter** (Pype setup tool) will launch its GUI. +If no OpenPype repositories are found in `OPENPYPE_PATH` (user data dir) +then **Igniter** (OpenPype setup tool) will launch its GUI. -It can be used to specify `PYPE_PATH` or if it is _not_ specified, current +It can be used to specify `OPENPYPE_PATH` or if it is _not_ specified, current *"live"* repositories will be used to create zip file and copy it to appdata dir in user home and extract it there. Version will be determined by -version specified in Pype module. +version specified in OpenPype module. -If Pype repository directories are found in default install location -(user data dir) or in `PYPE_PATH`, it will get list of those dirs there and +If OpenPype repository directories are found in default install location +(user data dir) or in `OPENPYPE_PATH`, it will get list of those dirs there and use latest one or the one specified with optional `--use-version` command line argument. If the one specified doesn't exist then latest available version will be used. All repositories in that dir will be added to `sys.path` and `PYTHONPATH`. -If Pype is live (not frozen) then current version of Pype module will be +If OpenPype is live (not frozen) then current version of OpenPype module will be used. All directories under `repos` will be added to `sys.path` and `PYTHONPATH`. -Pype depends on connection to `MongoDB`_. You can specify MongoDB connection -string via `PYPE_MONGO` set in environment or it can be set in user +OpenPype depends on connection to `MongoDB`_. You can specify MongoDB connection +string via `OPENPYPE_MONGO` set in environment or it can be set in user settings or via **Igniter** GUI. -So, bootstrapping Pype looks like this:: +So, bootstrapping OpenPype looks like this:: .. code-block:: bash +-------------------------------------------------------+ | Determine MongoDB connection: | -| Use `PYPE_MONGO`, system keyring `pypeMongo` | +| Use `OPENPYPE_MONGO`, system keyring `openPypeMongo` | +--------------------------|----------------------------+ .--- Found? --. YES NO @@ -52,9 +52,9 @@ So, bootstrapping Pype looks like this:: | | | | +-----------------v------------------------------------+ | -| Get location of Pype: | | -| 1) Test for `PYPE_PATH` environment variable | | -| 2) Test `pypePath` in registry setting | | +| Get location of OpenPype: | | +| 1) Test for `OPENPYPE_PATH` environment variable | | +| 2) Test `openPypePath` in registry setting | | | 3) Test user data directory | | | ................................................... | | | If running from frozen code: | | @@ -63,21 +63,21 @@ So, bootstrapping Pype looks like this:: | - Use live code and install it to user data dir | | | * can be overridden with `--use-version` argument | | +-------------------------|----------------------------+ | - .-- Is Pype found? --. | - YES NO | - | | | - | +--------------v------------------+ | - | | Look in `PYPE_PATH`, find | | + .-- Is OpenPype found? --. | + YES NO | + | | | + | +---------------v-----------------+ | + | | Look in `OPENPYPE_PATH`, find | | | | latest version and install it | | | | to user data dir. | | | +--------------|------------------+ | - | .-- Is Pype found? --. | - | YES NO ---------+ + | .-- Is OpenPype found? --. | + | YES NO --------+ | | |<---------+ | +-------------v------------+ -| Run Pype | +| Run OpenPype | +--------------------------+ @@ -85,7 +85,7 @@ Todo: Move or remove bootstrapping environments out of the code. Attributes: - silent_commands (list): list of commands for which we won't print Pype + silent_commands (list): list of commands for which we won't print OpenPype logo and info header. .. _MongoDB: diff --git a/tools/build.ps1 b/tools/build.ps1 index e0a74bbaa3..70e6b68377 100644 --- a/tools/build.ps1 +++ b/tools/build.ps1 @@ -1,11 +1,12 @@ <# .SYNOPSIS - Helper script to build Pype. + Helper script to build OpenPype. .DESCRIPTION - This script will detect Python installation, create venv and install - all necessary packages from `requirements.txt` needed by Pype to be - included during application freeze on Windows. + This script will detect Python installation, and build OpenPype to `build` + directory using existing virtual environment created by Poetry (or + by running `/tools/create_venv.ps1`). It will then shuffle dependencies in + build folder to optimize for different Python versions (2/3) in Python host. .EXAMPLE @@ -75,14 +76,11 @@ function Install-Poetry() { $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -93,28 +91,28 @@ Write-Host $art -ForegroundColor DarkGreen $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName +$openpype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +Set-Location -Path $openpype_root -$version_file = Get-Content -Path "$($pype_root)\pype\version.py" +$version_file = Get-Content -Path "$($openpype_root)\pype\version.py" $result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"') -$pype_version = $result[0].Groups['version'].Value -if (-not $pype_version) { +$openpype_version = $result[0].Groups['version'].Value +if (-not $openpype_version) { Write-Host "!!! " -ForegroundColor yellow -NoNewline - Write-Host "Cannot determine Pype version." + Write-Host "Cannot determine OpenPype version." Exit-WithCode 1 } # Create build directory if not exist -if (-not (Test-Path -PathType Container -Path "$($pype_root)\build")) { - New-Item -ItemType Directory -Force -Path "$($pype_root)\build" +if (-not (Test-Path -PathType Container -Path "$($openpype_root)\build")) { + New-Item -ItemType Directory -Force -Path "$($openpype_root)\build" } Write-Host "--- " -NoNewline -ForegroundColor yellow Write-Host "Cleaning build directory ..." try { - Remove-Item -Recurse -Force "$($pype_root)\build\*" + Remove-Item -Recurse -Force "$($openpype_root)\build\*" } catch { Write-Host "!!! " -NoNewline -ForegroundColor Red @@ -124,8 +122,8 @@ catch { } Write-Host ">>> " -NoNewline -ForegroundColor green -Write-Host "Building Pype [ " -NoNewline -ForegroundColor white -Write-host $pype_version -NoNewline -ForegroundColor green +Write-Host "Building OpenPype [ " -NoNewline -ForegroundColor white +Write-host $openpype_version -NoNewline -ForegroundColor green Write-Host " ] ..." -ForegroundColor white Write-Host ">>> " -NoNewline -ForegroundColor green @@ -167,31 +165,31 @@ if (-not (Test-Path -PathType Container -Path "$($env:USERPROFILE)\.poetry\bin") Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Cleaning cache files ... " -NoNewline -Get-ChildItem $pype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force -Get-ChildItem $pype_root -Filter "*.pyo" -Force -Recurse | Remove-Item -Force -Get-ChildItem $pype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse +Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse Write-Host "OK" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green -Write-Host "Building Pype ..." +Write-Host "Building OpenPype ..." $out = & poetry run python setup.py build 2>&1 if ($LASTEXITCODE -ne 0) { - Set-Content -Path "$($pype_root)\build\build.log" -Value $out + Set-Content -Path "$($openpype_root)\build\build.log" -Value $out Write-Host "!!! " -NoNewLine -ForegroundColor Red Write-Host "Build failed. Check the log: " -NoNewline Write-Host ".\build\build.log" -ForegroundColor Yellow Exit-WithCode $LASTEXITCODE } -Set-Content -Path "$($pype_root)\build\build.log" -Value $out -& poetry run python "$($pype_root)\tools\build_dependencies.py" +Set-Content -Path "$($openpype_root)\build\build.log" -Value $out +& poetry run python "$($openpype_root)\tools\build_dependencies.py" Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "restoring current directory" Set-Location -Path $current_dir Write-Host "*** " -NoNewline -ForegroundColor Cyan -Write-Host "All done. You will find Pype and build log in " -NoNewLine +Write-Host "All done. You will find OpenPype and build log in " -NoNewLine Write-Host "'.\build'" -NoNewline -ForegroundColor Green Write-Host " directory." diff --git a/tools/build.sh b/tools/build.sh index 27d10f1d4d..b95e2969c4 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -5,13 +5,12 @@ art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -93,7 +92,7 @@ detect_python () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -136,16 +135,16 @@ main () { detect_python || return 1 # Directories - pype_root=$(dirname $(dirname "$(realpath ${BASH_SOURCE[0]})")) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(dirname $(dirname "$(realpath ${BASH_SOURCE[0]})")) + pushd "$openpype_root" > /dev/null || return > /dev/null - version_command="import os;exec(open(os.path.join('$pype_root', 'pype', 'version.py')).read());print(__version__);" - pype_version="$(python3 <<< ${version_command})" + version_command="import os;exec(open(os.path.join('$openpype_root', 'openpype', 'version.py')).read());print(__version__);" + openpype_version="$(python3 <<< ${version_command})" echo -e "${BIYellow}---${RST} Cleaning build directory ..." - rm -rf "$pype_root/build" && mkdir "$pype_root/build" > /dev/null + rm -rf "$openpype_root/build" && mkdir "$openpype_root/build" > /dev/null - echo -e "${BIGreen}>>>${RST} Building Pype ${BIWhite}[${RST} ${BIGreen}$pype_version${RST} ${BIWhite}]${RST}" + echo -e "${BIGreen}>>>${RST} Building OpenPype ${BIWhite}[${RST} ${BIGreen}$openpype_version${RST} ${BIWhite}]${RST}" echo -e "${BIGreen}>>>${RST} Cleaning cache files ..." clean_pyc @@ -159,11 +158,11 @@ main () { fi echo -e "${BIGreen}>>>${RST} Building ..." - poetry run python3 "$pype_root/setup.py" build > "$pype_root/build/build.log" || { echo -e "${BIRed}!!!${RST} Build failed, see the build log."; return; } - poetry run python3 "$pype_root/tools/build_dependencies.py" + poetry run python3 "$openpype_root/setup.py" build > "$openpype_root/build/build.log" || { echo -e "${BIRed}!!!${RST} Build failed, see the build log."; return; } + poetry run python3 "$openpype_root/tools/build_dependencies.py" - echo -e "${BICyan}>>>${RST} All done. You will find Pype and build log in \c" - echo -e "${BIWhite}$pype_root/build${RST} directory." + echo -e "${BICyan}>>>${RST} All done. You will find OpenPype and build log in \c" + echo -e "${BIWhite}$openpype_root/build${RST} directory." } main diff --git a/tools/build_dependencies.py b/tools/build_dependencies.py index ada786e96f..e49e930a70 100644 --- a/tools/build_dependencies.py +++ b/tools/build_dependencies.py @@ -101,8 +101,8 @@ for d in libs_dir.iterdir(): to_delete.append(d) _print(f"found {d}", 3) -# add pype and igniter in libs too -to_delete.append(libs_dir / "pype") +# add openpype and igniter in libs too +to_delete.append(libs_dir / "openpype") to_delete.append(libs_dir / "igniter") # delete duplicates diff --git a/tools/create_env.ps1 b/tools/create_env.ps1 index ccc0cab2e7..44e1799be8 100644 --- a/tools/create_env.ps1 +++ b/tools/create_env.ps1 @@ -1,11 +1,11 @@ <# .SYNOPSIS - Helper script create virtual env. + Helper script create virtual environment using Poetry. .DESCRIPTION - This script will detect Python installation, create venv and install - all necessary packages from `requirements.txt` needed by Pype to be - included during application freeze on Windows. + This script will detect Python installation, create venv with Poetry + and install all necessary packages from `poetry.lock` or `pyproject.toml` + needed by OpenPype to be included during application freeze on Windows. .EXAMPLE @@ -82,20 +82,17 @@ print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1])) $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName +$openpype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +Set-Location -Path $openpype_root $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -104,18 +101,18 @@ Write-Host $art -ForegroundColor DarkGreen # Enable if PS 7.x is needed. # Show-PSWarning -$version_file = Get-Content -Path "$($pype_root)\pype\version.py" +$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py" $result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"') -$pype_version = $result[0].Groups['version'].Value -if (-not $pype_version) { +$openpype_version = $result[0].Groups['version'].Value +if (-not $openpype_version) { Write-Host "!!! " -ForegroundColor yellow -NoNewline - Write-Host "Cannot determine Pype version." + Write-Host "Cannot determine OpenPype version." Set-Location -Path $current_dir Exit-WithCode 1 } Write-Host ">>> " -NoNewline -ForegroundColor Green -Write-Host "Found Pype version " -NoNewline -Write-Host "[ $($pype_version) ]" -ForegroundColor Green +Write-Host "Found OpenPype version " -NoNewline +Write-Host "[ $($openpype_version) ]" -ForegroundColor Green Test-Python @@ -129,7 +126,7 @@ if (-not (Test-Path -PathType Container -Path "$($env:USERPROFILE)\.poetry\bin") Write-Host "OK" -ForegroundColor Green } -if (-not (Test-Path -PathType Leaf -Path "$($pype_root)\poetry.lock")) { +if (-not (Test-Path -PathType Leaf -Path "$($openpype_root)\poetry.lock")) { Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Installing virtual environment and creating lock." } else { @@ -145,4 +142,4 @@ if ($LASTEXITCODE -ne 0) { } Set-Location -Path $current_dir Write-Host ">>> " -NoNewline -ForegroundColor green -Write-Host "Virtual environment created. " \ No newline at end of file +Write-Host "Virtual environment created." diff --git a/tools/create_env.sh b/tools/create_env.sh index 52bc79ca83..6ca0731963 100755 --- a/tools/create_env.sh +++ b/tools/create_env.sh @@ -1,19 +1,17 @@ #!/usr/bin/env bash -# This script will detect Python installation, and create virtual environment -# for Pype to run or build. - +# This script will detect Python installation, create venv with Poetry +# and install all necessary packages from `poetry.lock` or `pyproject.toml` +# needed by OpenPype to be included during application freeze on unix. art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -117,7 +115,7 @@ install_poetry () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -144,8 +142,8 @@ main () { detect_python || return 1 # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" > /dev/null || return > /dev/null echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c" if [ -f "$HOME/.poetry/bin/poetry" ]; then @@ -156,7 +154,7 @@ main () { install_poetry || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return; } fi - if [ -f "$pype_root/poetry.lock" ]; then + if [ -f "$openpype_root/poetry.lock" ]; then echo -e "${BIGreen}>>>${RST} Updating dependencies ..." else echo -e "${BIGreen}>>>${RST} Installing dependencies ..." diff --git a/tools/create_zip.ps1 b/tools/create_zip.ps1 index 900bc0d523..d18806c40b 100644 --- a/tools/create_zip.ps1 +++ b/tools/create_zip.ps1 @@ -1,11 +1,12 @@ <# .SYNOPSIS - Helper script create distributable Pype zip. + Helper script create distributable OpenPype zip. .DESCRIPTION - This script will detect Python installation, create venv and install - all necessary packages from `requirements.txt` needed by Pype to be - included during application freeze on Windows. + This script will detect Python installation and run OpenPype to create + zip. It needs mongodb running. I will create zip from current source code + version and copy it top `%LOCALAPPDATA%/pypeclub/pype` if `--path` or `-p` + argument is not used. .EXAMPLE @@ -35,19 +36,16 @@ function Show-PSWarning() { $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +$openpype_root = (Get-Item $script_dir).parent.FullName +Set-Location -Path $openpype_root $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -56,12 +54,12 @@ Write-Host $art -ForegroundColor DarkGreen # Enable if PS 7.x is needed. # Show-PSWarning -$version_file = Get-Content -Path "$($pype_root)\pype\version.py" +$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py" $result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"') -$pype_version = $result[0].Groups['version'].Value -if (-not $pype_version) { +$openpype_version = $result[0].Groups['version'].Value +if (-not $openpype_version) { Write-Host "!!! " -ForegroundColor yellow -NoNewline - Write-Host "Cannot determine Pype version." + Write-Host "Cannot determine OpenPype version." Exit-WithCode 1 } @@ -95,5 +93,5 @@ Write-Host "Generating zip from current sources ..." Write-Host "... " -NoNewline -ForegroundColor Magenta Write-Host "arguments: " -NoNewline -ForegroundColor Gray Write-Host $ARGS -ForegroundColor White -& poetry run python "$($pype_root)\start.py" generate-zip $ARGS +& poetry run python "$($openpype_root)\start.py" generate-zip $ARGS Set-Location -Path $current_dir \ No newline at end of file diff --git a/tools/create_zip.sh b/tools/create_zip.sh index 839b1c4827..6e7f792f1d 100755 --- a/tools/create_zip.sh +++ b/tools/create_zip.sh @@ -1,17 +1,18 @@ #!/usr/bin/env bash -# Helper script to create Pype zip. - +# This script will detect Python installation and run OpenPype to create +# zip. It needs mongodb running. I will create zip from current source code +# version and copy it top `~/.local/share/pype` if `--path` or `-p` +# argument is not used. art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -91,7 +92,7 @@ detect_python () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -118,11 +119,11 @@ main () { detect_python || return 1 # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" > /dev/null || return > /dev/null echo -e "${BIGreen}>>>${RST} Generating zip from current sources ..." - poetry run python3 "$pype_root/start.py" generate-zip "$@" + poetry run python3 "$openpype_root/start.py" generate-zip "$@" } main "$@" diff --git a/tools/make_docs.ps1 b/tools/make_docs.ps1 index 8ce991d5bb..aa526bbdc9 100644 --- a/tools/make_docs.ps1 +++ b/tools/make_docs.ps1 @@ -1,9 +1,9 @@ <# .SYNOPSIS - Helper script to update Pype Sphinx sources. + Helper script to update OpenPype Sphinx sources. .DESCRIPTION - This script will run apidoc over Pype sources and generate new source rst + This script will run apidoc over OpenPype sources and generate new source rst files for documentation. Then it will run build_sphinx to create test html documentation build. @@ -15,33 +15,31 @@ PS> .\make_docs.ps1 $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +$openpype_root = (Get-Item $script_dir).parent.FullName +Set-Location -Path $openpype_root $art = @" - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ Write-Host $art -ForegroundColor DarkGreen Write-Host "This will not overwrite existing source rst files, only scan and add new." -Set-Location -Path $pype_root +Set-Location -Path $openpype_root Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Running apidoc ..." -& poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($pype_root)\docs\source" igniter -& poetry run sphinx-apidoc.exe -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($pype_root)\docs\source" pype vendor, pype\vendor +& poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($openpype_root)\docs\source" igniter +& poetry run sphinx-apidoc.exe -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($openpype_root)\docs\source" openpype vendor, openpype\vendor Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Building html ..." -& poetry run python "$($pype_root)\setup.py" build_sphinx +& poetry run python "$($openpype_root)\setup.py" build_sphinx Set-Location -Path $current_dir diff --git a/tools/make_docs.sh b/tools/make_docs.sh index ed5c72b055..2ac12d3d95 100755 --- a/tools/make_docs.sh +++ b/tools/make_docs.sh @@ -1,18 +1,17 @@ #!/usr/bin/env bash -# Make Pype documentation - +# This script will run apidoc over OpenPype sources and generate new source rst +# files for documentation. Then it will run build_sphinx to create test html +# documentation build. art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -71,15 +70,15 @@ main () { echo -e "${RST}" # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" > /dev/null || return > /dev/null echo -e "${BIGreen}>>>${RST} Running apidoc ..." - poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$pype_root/docs/source" igniter - poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$pype_root/docs/source" pype vendor, pype\vendor + poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$openpype_root/docs/source" igniter + poetry run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$openpype_root/docs/source" openpype vendor, openpype\vendor echo -e "${BIGreen}>>>${RST} Building html ..." - poetry run python3 "$pype_root/setup.py" build_sphinx + poetry run python3 "$openpype_root/setup.py" build_sphinx } main diff --git a/tools/run_mongo.ps1 b/tools/run_mongo.ps1 index a72c8b1210..da5f4aaa26 100644 --- a/tools/run_mongo.ps1 +++ b/tools/run_mongo.ps1 @@ -13,14 +13,11 @@ PS> .\run_mongo.ps1 $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -80,13 +77,13 @@ function Find-Mongo { } $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName +$openpype_root = (Get-Item $script_dir).parent.FullName # mongodb port $port = 2707 # path to database -$dbpath = (Get-Item $pype_root).parent.FullName + "\mongo_db_data" +$dbpath = (Get-Item $openpype_root).parent.FullName + "\mongo_db_data" Find-Mongo $mongo = Get-Command "mongod" | Select-Object -ExpandProperty Definition diff --git a/tools/run_mongo.sh b/tools/run_mongo.sh index 209e80ac5b..1c788abcaf 100755 --- a/tools/run_mongo.sh +++ b/tools/run_mongo.sh @@ -6,13 +6,12 @@ art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -72,11 +71,11 @@ main () { echo -e "${RST}" # Directories - pype_root=$(dirname $(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(dirname $(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))) + pushd "$openpype_root" > /dev/null || return > /dev/null mongo_port=2707 - dbpath="$(dirname $pype_root)/mongo_db_data" + dbpath="$(dirname $openpype_root)/mongo_db_data" echo -e "${BIGreen}>>>${RST} Running mongodb ..." mongod --dbpath "$dbpath" --port $mongo_port diff --git a/tools/run_settings.ps1 b/tools/run_settings.ps1 index acecae0bb6..3f99de4b4e 100644 --- a/tools/run_settings.ps1 +++ b/tools/run_settings.ps1 @@ -1,9 +1,9 @@ <# .SYNOPSIS - Helper script to Pype Settings UI + Helper script to OpenPype Settings UI .DESCRIPTION - This script will run Pype and open Settings UI. + This script will run OpenPype and open Settings UI. .EXAMPLE @@ -13,7 +13,7 @@ PS> .\run_settings.ps1 $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root -& poetry run python "$($pype_root)\start.py" settings --dev +$openpype_root = (Get-Item $script_dir).parent.FullName +Set-Location -Path $openpype_root +& poetry run python "$($openpype_root)\start.py" settings --dev Set-Location -Path $current_dir \ No newline at end of file diff --git a/tools/run_settings.sh b/tools/run_settings.sh index 99148456c0..0c8a951d7c 100755 --- a/tools/run_settings.sh +++ b/tools/run_settings.sh @@ -1,17 +1,16 @@ #!/usr/bin/env bash -# Run Pype Settings GUI +# Run OpenPype Settings GUI art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -91,7 +90,7 @@ detect_python () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$oepnpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -118,11 +117,11 @@ main () { detect_python || return 1 # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" > /dev/null || return > /dev/null echo -e "${BIGreen}>>>${RST} Generating zip from current sources ..." - poetry run python3 "$pype_root/start.py" settings --dev + poetry run python3 "$openpype_root/start.py" settings --dev } main diff --git a/tools/run_tests.ps1 b/tools/run_tests.ps1 index 0f66c0079f..5070591c02 100644 --- a/tools/run_tests.ps1 +++ b/tools/run_tests.ps1 @@ -1,11 +1,9 @@ <# .SYNOPSIS - Helper script to build Pype. + Helper script to run tests for OpenPype. .DESCRIPTION - This script will detect Python installation, create venv and install - all necessary packages from `requirements.txt` needed by Pype to be - included during application freeze on Windows. + This will use virtual environment and pytest to run test for OpenPype. .EXAMPLE @@ -34,14 +32,11 @@ function Show-PSWarning() { $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -52,22 +47,22 @@ Write-Host $art -ForegroundColor DarkGreen $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName +$openpype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +Set-Location -Path $openpype_root -$version_file = Get-Content -Path "$($pype_root)\pype\version.py" +$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py" $result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"') -$pype_version = $result[0].Groups['version'].Value -if (-not $pype_version) { +$openpype_version = $result[0].Groups['version'].Value +if (-not $openpype_version) { Write-Host "!!! " -ForegroundColor yellow -NoNewline - Write-Host "Cannot determine Pype version." + Write-Host "Cannot determine OpenPype version." Exit-WithCode 1 } Write-Host ">>> " -NoNewline -ForegroundColor green -Write-Host "Building Pype [ " -NoNewline -ForegroundColor white -Write-host $pype_version -NoNewline -ForegroundColor green +Write-Host "Building OpenPype [ " -NoNewline -ForegroundColor white +Write-host $openpype_version -NoNewline -ForegroundColor green Write-Host " ] ..." -ForegroundColor white Write-Host ">>> " -NoNewline -ForegroundColor green @@ -97,15 +92,15 @@ Write-Host "OK [ $p ]" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Cleaning cache files ... " -NoNewline -Get-ChildItem $pype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force -Get-ChildItem $pype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse +Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse Write-Host "OK" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green -Write-Host "Testing Pype ..." +Write-Host "Testing OpenPype ..." $original_pythonpath = $env:PYTHONPATH -$env:PYTHONPATH="$($pype_root);$($env:PYTHONPATH)" -& poetry run pytest -x --capture=sys --print -W ignore::DeprecationWarning "$($pype_root)/tests" +$env:PYTHONPATH="$($openpype_root);$($env:PYTHONPATH)" +& poetry run pytest -x --capture=sys --print -W ignore::DeprecationWarning "$($openpype_root)/tests" $env:PYTHONPATH = $original_pythonpath Write-Host ">>> " -NoNewline -ForegroundColor green diff --git a/tools/run_tests.sh b/tools/run_tests.sh index df001dce97..0af052ca01 100755 --- a/tools/run_tests.sh +++ b/tools/run_tests.sh @@ -1,17 +1,16 @@ #!/usr/bin/env bash -# Run tests for Pype - +# Run tests for OpenPype +# This will use virtual environment and pytest to run test for OpenPype. art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -87,7 +86,7 @@ detect_python () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -114,13 +113,13 @@ main () { detect_python || return 1 # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" || return > /dev/null - echo -e "${BIGreen}>>>${RST} Testing Pype ..." + echo -e "${BIGreen}>>>${RST} Testing OpenPype ..." original_pythonpath=$PYTHONPATH - export PYTHONPATH="$pype_root:$PYTHONPATH" - poetry run pytest -x --capture=sys --print -W ignore::DeprecationWarning "$pype_root/tests" + export PYTHONPATH="$openpype_root:$PYTHONPATH" + poetry run pytest -x --capture=sys --print -W ignore::DeprecationWarning "$openpype_root/tests" PYTHONPATH=$original_pythonpath } diff --git a/tools/run_tray.ps1 b/tools/run_tray.ps1 index 9584c05925..9485584c6f 100644 --- a/tools/run_tray.ps1 +++ b/tools/run_tray.ps1 @@ -1,6 +1,6 @@ <# .SYNOPSIS - Helper script Pype Tray. + Helper script OpenPype Tray. .DESCRIPTION @@ -12,8 +12,8 @@ PS> .\run_tray.ps1 #> $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +$openpype_root = (Get-Item $script_dir).parent.FullName +Set-Location -Path $openpype_root -& poetry run python "$($pype_root)\start.py" tray --debug +& poetry run python "$($openpype_root)\start.py" tray --debug Set-Location -Path $current_dir \ No newline at end of file diff --git a/tools/run_tray.sh b/tools/run_tray.sh index 3c63d0babe..8174f7e38a 100755 --- a/tools/run_tray.sh +++ b/tools/run_tray.sh @@ -1,17 +1,16 @@ #!/usr/bin/env bash -# Run Pype Tray +# Run OpenPype Tray art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io EOF } @@ -92,7 +91,7 @@ detect_python () { ############################################################################### clean_pyc () { local path - path=$pype_root + path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" @@ -119,11 +118,11 @@ main () { detect_python || return 1 # Directories - pype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) - pushd "$pype_root" > /dev/null || return > /dev/null + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + pushd "$openpype_root" > /dev/null || return > /dev/null - echo -e "${BIGreen}>>>${RST} Running Pype Tray with debug option ..." - poetry run python3 "$pype_root/start.py" tray --debug + echo -e "${BIGreen}>>>${RST} Running OpenPype Tray with debug option ..." + poetry run python3 "$openpype_root/start.py" tray --debug } main \ No newline at end of file diff --git a/tools/update_submodules.ps1 b/tools/update_submodules.ps1 index ca29c7ecc4..d0f93d9f7e 100644 --- a/tools/update_submodules.ps1 +++ b/tools/update_submodules.ps1 @@ -1,26 +1,20 @@ <# .SYNOPSIS - Helper script to run mongodb. - -.DESCRIPTION - This script will detect mongodb, add it to the PATH and launch it on specified port and db location. + Helper script to update submodules. .EXAMPLE -PS> .\run_mongo.ps1 +PS> .\update_submodules.ps1 #> $art = @" - - ____________ - /\ ___ \ - \ \ \/_\ \ - \ \ _____/ ______ ___ ___ ___ - \ \ \___/ /\ \ \ \\ \\ \ - \ \____\ \ \_____\ \__\\__\\__\ - \/____/ \/_____/ . PYPE Club . +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. + https://openpype.io "@ @@ -37,9 +31,9 @@ function Exit-WithCode($exitcode) { $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -$pype_root = (Get-Item $script_dir).parent.FullName +$openpype_root = (Get-Item $script_dir).parent.FullName -Set-Location -Path $pype_root +Set-Location -Path $openpype_root git submodule update --recursive --remote diff --git a/tools/update_submodules.sh b/tools/update_submodules.sh index 35d943dea5..465827bfbb 100644 --- a/tools/update_submodules.sh +++ b/tools/update_submodules.sh @@ -1,17 +1,15 @@ #!/usr/bin/env bash -# Run Pype Tray +# Run OpenPype Tray art () { cat <<-EOF - ____________ - /\\ ___ \\ - \\ \\ \\/_\\ \\ - \\ \\ _____/ ______ ___ ___ ___ - \\ \\ \\___/ /\\ \\ \\ \\\\ \\\\ \\ - \\ \\____\\ \\ \\_____\\ \\__\\\\__\\\\__\\ - \\/____/ \\/_____/ . PYPE Club . + +▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀█ █░░█ █▀▀█ █▀▀ ▀█▀ ▀█▀ ▀█▀ +▒█░░▒█ █░░█ █▀▀ █░░█ ▒█▄▄█ █▄▄█ █░░█ █▀▀ ▒█░ ▒█░ ▒█░ +▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█░░░ ▄▄▄█ █▀▀▀ ▀▀▀ ▄█▄ ▄█▄ ▄█▄ + .---= [ by Pype Club ] =---. EOF } From 8e44150deb2a9e0af083a7329288871849cfb55d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 15:04:26 +0200 Subject: [PATCH 232/295] remove publish_filesequence which is not used anymore --- pype/scripts/publish_filesequence.py | 97 ---------------------------- 1 file changed, 97 deletions(-) delete mode 100644 pype/scripts/publish_filesequence.py diff --git a/pype/scripts/publish_filesequence.py b/pype/scripts/publish_filesequence.py deleted file mode 100644 index 905c6b99ba..0000000000 --- a/pype/scripts/publish_filesequence.py +++ /dev/null @@ -1,97 +0,0 @@ -"""This module is used for command line publishing of image sequences.""" - -import os -import sys -import argparse -import logging -import subprocess -import platform -import json - -try: - from shutil import which -except ImportError: - # we are in python < 3.3 - def which(command): - path = os.getenv('PATH') - for p in path.split(os.path.pathsep): - p = os.path.join(p, command) - if os.path.exists(p) and os.access(p, os.X_OK): - return p - -handler = logging.basicConfig() -log = logging.getLogger("Publish Image Sequences") -log.setLevel(logging.DEBUG) - -error_format = "Failed {plugin.__name__}: {error} -- {error.traceback}" - - -def __main__(): - parser = argparse.ArgumentParser() - parser.add_argument("--paths", - nargs="*", - default=[], - help="The filepaths to publish. This can be a " - "directory or a path to a .json publish " - "configuration.") - parser.add_argument("--gui", - default=False, - action="store_true", - help="Whether to run Pyblish in GUI mode.") - - parser.add_argument("--pype", help="Pype root") - - kwargs, args = parser.parse_known_args() - - print("Running pype ...") - auto_pype_root = os.path.dirname(os.path.abspath(__file__)) - auto_pype_root = os.path.abspath(auto_pype_root + "../../../../..") - - auto_pype_root = os.environ.get('PYPE_SETUP_PATH') or auto_pype_root - if os.environ.get('PYPE_SETUP_PATH'): - print("Got Pype location from environment: {}".format( - os.environ.get('PYPE_SETUP_PATH'))) - - pype_command = "pype.ps1" - if platform.system().lower() == "linux": - pype_command = "pype" - elif platform.system().lower() == "windows": - pype_command = "pype.bat" - - if kwargs.pype: - pype_root = kwargs.pype - else: - # test if pype.bat / pype is in the PATH - # if it is, which() will return its path and we use that. - # if not, we use auto_pype_root path. Caveat of that one is - # that it can be UNC path and that will not work on windows. - - pype_path = which(pype_command) - - if pype_path: - pype_root = os.path.dirname(pype_path) - else: - pype_root = auto_pype_root - - print("Set pype root to: {}".format(pype_root)) - print("Paths: {}".format(kwargs.paths or [os.getcwd()])) - - paths = kwargs.paths or [os.environ.get("PYPE_METADATA_FILE")] or [os.getcwd()] # noqa - args = [ - os.path.join(pype_root, pype_command), - "publish", - " ".join(['"{}"'.format(p) for p in paths]) - ] - - print("Pype command: {}".format(" ".join(args))) - # Forcing forwaring the environment because environment inheritance does - # not always work. - # Cast all values in environment to str to be safe - env = {k: str(v) for k, v in os.environ.items()} - exit_code = subprocess.call(args, env=env) - if exit_code != 0: - raise RuntimeError("Publishing failed.") - - -if __name__ == '__main__': - __main__() From 2328fc446eba431b64a55b19d845f4dbb42ae8f1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 15:10:00 +0200 Subject: [PATCH 233/295] change environments in default settings --- .../system_settings/applications.json | 66 +++++++++---------- .../defaults/system_settings/general.json | 10 +-- .../defaults/system_settings/tools.json | 2 +- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/pype/settings/defaults/system_settings/applications.json b/pype/settings/defaults/system_settings/applications.json index 5eccdfb83d..b21b035e38 100644 --- a/pype/settings/defaults/system_settings/applications.json +++ b/pype/settings/defaults/system_settings/applications.json @@ -6,9 +6,9 @@ "host_name": "maya", "environment": { "PYTHONPATH": [ - "{PYPE_ROOT}/pype/hosts/maya/startup", - "{PYPE_REPOS_ROOT}/avalon-core/setup/maya", - "{PYPE_REPOS_ROOT}/maya-look-assigner", + "{OPENPYPE_ROOT}/pype/hosts/maya/startup", + "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/maya", + "{OPENPYPE_REPOS_ROOT}/maya-look-assigner", "{PYTHONPATH}" ], "MAYA_DISABLE_CLIC_IPM": "Yes", @@ -16,7 +16,7 @@ "MAYA_DISABLE_CER": "Yes", "PYMEL_SKIP_MEL_INIT": "Yes", "LC_ALL": "C", - "PYPE_LOG_NO_COLORS": "Yes" + "OPENPYPE_LOG_NO_COLORS": "Yes" }, "variants": { "maya_2020": { @@ -91,8 +91,8 @@ "host_name": "maya", "environment": { "PYTHONPATH": [ - "{PYPE_REPOS_ROOT}/avalon-core/setup/maya", - "{PYPE_REPOS_ROOT}/maya-look-assigner", + "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/maya", + "{OPENPYPE_REPOS_ROOT}/maya-look-assigner", "{PYTHON_ENV}/python2/Lib/site-packages", "{PYTHONPATH}" ], @@ -101,7 +101,7 @@ "MAYA_DISABLE_CER": "Yes", "PYMEL_SKIP_MEL_INIT": "Yes", "LC_ALL": "C", - "PYPE_LOG_NO_COLORS": "Yes", + "OPENPYPE_LOG_NO_COLORS": "Yes", "MAYA_TEST": "{MAYA_VERSION}" }, "variants": { @@ -171,9 +171,9 @@ "host_name": "nuke", "environment": { "NUKE_PATH": [ - "{PYPE_REPOS_ROOT}/avalon-core/setup/nuke/nuke_path", - "{PYPE_ROOT}/pype/hosts/nuke/startup", - "{PYPE_STUDIO_PLUGINS}/nuke" + "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/nuke/nuke_path", + "{OPENPYPE_ROOT}/pype/hosts/nuke/startup", + "{OPENPYPE_STUDIO_PLUGINS}/nuke" ], "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" @@ -264,9 +264,9 @@ "host_name": "nuke", "environment": { "NUKE_PATH": [ - "{PYPE_REPOS_ROOT}/avalon-core/setup/nuke/nuke_path", - "{PYPE_ROOT}/pype/hosts/nuke/startup", - "{PYPE_STUDIO_PLUGINS}/nuke" + "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/nuke/nuke_path", + "{OPENPYPE_ROOT}/pype/hosts/nuke/startup", + "{OPENPYPE_STUDIO_PLUGINS}/nuke" ], "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" @@ -381,7 +381,7 @@ "host_name": "hiero", "environment": { "HIERO_PLUGIN_PATH": [ - "{PYPE_ROOT}/pype/hosts/hiero/startup" + "{OPENPYPE_ROOT}/pype/hosts/hiero/startup" ], "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" @@ -496,7 +496,7 @@ "host_name": "hiero", "environment": { "HIERO_PLUGIN_PATH": [ - "{PYPE_ROOT}/pype/hosts/hiero/startup" + "{OPENPYPE_ROOT}/pype/hosts/hiero/startup" ], "PATH": { "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" @@ -633,7 +633,7 @@ "{PYTHON36}/Scripts", "{PATH}" ], - "PYPE_LOG_NO_COLORS": "Yes" + "OPENPYPE_LOG_NO_COLORS": "Yes" }, "variants": { "fusion_16": { @@ -709,8 +709,8 @@ "{PYTHON36_RESOLVE}/Scripts", "{PATH}" ], - "PRE_PYTHON_SCRIPT": "{PYPE_ROOT}/pype/resolve/preload_console.py", - "PYPE_LOG_NO_COLORS": "True", + "PRE_PYTHON_SCRIPT": "{OPENPYPE_ROOT}/pype/resolve/preload_console.py", + "OPENPYPE_LOG_NO_COLORS": "True", "RESOLVE_DEV": "True" }, "variants": { @@ -740,14 +740,14 @@ "host_name": "houdini", "environment": { "HOUDINI_PATH": { - "darwin": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", - "linux": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", - "windows": "{PYPE_ROOT}/pype/hosts/houdini/startup;&" + "darwin": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup:&", + "linux": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup:&", + "windows": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup;&" }, "HOUDINI_MENU_PATH": { - "darwin": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", - "linux": "{PYPE_ROOT}/pype/hosts/houdini/startup:&", - "windows": "{PYPE_ROOT}/pype/hosts/houdini/startup;&" + "darwin": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup:&", + "linux": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup:&", + "windows": "{OPENPYPE_ROOT}/pype/hosts/houdini/startup;&" } }, "variants": { @@ -806,9 +806,9 @@ "icon": "{}/app_icons/blender.png", "host_name": "blender", "environment": { - "BLENDER_USER_SCRIPTS": "{PYPE_REPOS_ROOT}/avalon-core/setup/blender", + "BLENDER_USER_SCRIPTS": "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/blender", "PYTHONPATH": [ - "{PYPE_REPOS_ROOT}/avalon-core/setup/blender", + "{OPENPYPE_REPOS_ROOT}/avalon-core/setup/blender", "{PYTHONPATH}" ], "CREATE_NEW_CONSOLE": "yes" @@ -869,7 +869,7 @@ "host_name": "harmony", "environment": { "AVALON_HARMONY_WORKFILES_ON_LAUNCH": "1", - "LIB_OPENHARMONY_PATH": "{PYPE_ROOT}/pype/vendor/OpenHarmony" + "LIB_OPENHARMONY_PATH": "{OPENPYPE_ROOT}/pype/vendor/OpenHarmony" }, "variants": { "harmony_20": { @@ -912,7 +912,7 @@ "icon": "{}/app_icons/tvpaint.png", "host_name": "tvpaint", "environment": { - "PYPE_LOG_NO_COLORS": "True" + "OPENPYPE_LOG_NO_COLORS": "True" }, "variants": { "tvpaint_animation_11-64bits": { @@ -958,7 +958,7 @@ "host_name": "photoshop", "environment": { "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH": "1", - "PYPE_LOG_NO_COLORS": "Yes", + "OPENPYPE_LOG_NO_COLORS": "Yes", "WEBSOCKET_URL": "ws://localhost:8099/ws/", "WORKFILES_SAVE_AS": "Yes" }, @@ -1006,7 +1006,7 @@ "host_name": "aftereffects", "environment": { "AVALON_AFTEREFFECTS_WORKFILES_ON_LAUNCH": "1", - "PYPE_LOG_NO_COLORS": "Yes", + "OPENPYPE_LOG_NO_COLORS": "Yes", "WEBSOCKET_URL": "ws://localhost:8097/ws/", "WORKFILES_SAVE_AS": "Yes" }, @@ -1053,7 +1053,7 @@ "icon": "app_icons/celaction.png", "host_name": "celaction", "environment": { - "CELACTION_TEMPLATE": "{PYPE_ROOT}/pype/hosts/celaction/celaction_template_scene.scn" + "CELACTION_TEMPLATE": "{OPENPYPE_ROOT}/pype/hosts/celaction/celaction_template_scene.scn" }, "variants": { "celation_Local": { @@ -1075,8 +1075,8 @@ "icon": "{}/app_icons/ue4.png'", "host_name": "unreal", "environment": { - "AVALON_UNREAL_PLUGIN": "{PYPE_REPOS_ROOT}/avalon-unreal-integration", - "PYPE_LOG_NO_COLORS": "True", + "AVALON_UNREAL_PLUGIN": "{OPENPYPE_REPOS_ROOT}/avalon-unreal-integration", + "OPENPYPE_LOG_NO_COLORS": "True", "QT_PREFERRED_BINDING": "PySide" }, "variants": { diff --git a/pype/settings/defaults/system_settings/general.json b/pype/settings/defaults/system_settings/general.json index 99db4e85c6..eb9b6950c5 100644 --- a/pype/settings/defaults/system_settings/general.json +++ b/pype/settings/defaults/system_settings/general.json @@ -3,15 +3,15 @@ "studio_code": "stu", "environment": { "FFMPEG_PATH": { - "windows": "{PYPE_ROOT}/vendor/bin/ffmpeg_exec/windows/bin", - "darwin": "{PYPE_ROOT}/vendor/bin/ffmpeg_exec/darwin/bin", - "linux": ":{PYPE_ROOT}/vendor/bin/ffmpeg_exec/linux" + "windows": "{OPENPYPE_ROOT}/vendor/bin/ffmpeg_exec/windows/bin", + "darwin": "{OPENPYPE_ROOT}/vendor/bin/ffmpeg_exec/darwin/bin", + "linux": ":{OPENPYPE_ROOT}/vendor/bin/ffmpeg_exec/linux" }, - "PYPE_OCIO_CONFIG": "{STUDIO_SOFT}/OpenColorIO-Configs", + "OPENPYPE_OCIO_CONFIG": "{STUDIO_SOFT}/OpenColorIO-Configs", "__environment_keys__": { "global": [ "FFMPEG_PATH", - "PYPE_OCIO_CONFIG" + "OPENPYPE_OCIO_CONFIG" ] } }, diff --git a/pype/settings/defaults/system_settings/tools.json b/pype/settings/defaults/system_settings/tools.json index 214bfc95e5..535d8d5fdb 100644 --- a/pype/settings/defaults/system_settings/tools.json +++ b/pype/settings/defaults/system_settings/tools.json @@ -2,7 +2,7 @@ "tool_groups": { "mtoa": { "environment": { - "MTOA": "{PYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}", + "MTOA": "{OPENPYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}", "MAYA_RENDER_DESC_PATH": "{MTOA}", "MAYA_MODULE_PATH": "{MTOA}", "ARNOLD_PLUGIN_PATH": "{MTOA}/shaders", From 318ecf829eb57d736e22a7f4305dfeaeccf56d62 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 15:12:31 +0200 Subject: [PATCH 234/295] maya menu to openpype --- pype/hosts/maya/api/menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/maya/api/menu.py b/pype/hosts/maya/api/menu.py index 9381043511..cb04399a35 100644 --- a/pype/hosts/maya/api/menu.py +++ b/pype/hosts/maya/api/menu.py @@ -8,7 +8,7 @@ from pype.api import BuildWorkfile import maya.cmds as cmds self = sys.modules[__name__] -self._menu = os.environ.get('PYPE_STUDIO_NAME') or "Pype" +self._menu = "OpenPype" log = logging.getLogger(__name__) From fe4fb4ecffcc839a28cbbe59558258c5691ad48c Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 15:14:39 +0200 Subject: [PATCH 235/295] houdini openpype menu --- pype/hosts/houdini/startup/MainMenuCommon.XML | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/hosts/houdini/startup/MainMenuCommon.XML b/pype/hosts/houdini/startup/MainMenuCommon.XML index ba639a71a1..d1374cf7a3 100644 --- a/pype/hosts/houdini/startup/MainMenuCommon.XML +++ b/pype/hosts/houdini/startup/MainMenuCommon.XML @@ -2,7 +2,7 @@ <mainMenu> <menuBar> <subMenu id="avalon_menu"> - <label>Pype</label> + <label>OpenPype</label> <subMenu id="avalon_context"> <labelExpression><![CDATA[ from avalon import api @@ -19,7 +19,7 @@ from avalon.tools import contextmanager; contextmanager.show() <separatorItem/> <scriptItem id="avalon_create"> - <label>Create ...</label> + <label>Create</label> <scriptCode><![CDATA[ from avalon.tools import creator creator.show() @@ -27,7 +27,7 @@ creator.show() </scriptItem> <scriptItem id="avalon_load"> - <label>Load ...</label> + <label>Load</label> <scriptCode><![CDATA[ from avalon.tools import cbloader cbloader.show(use_context=True) @@ -35,7 +35,7 @@ cbloader.show(use_context=True) </scriptItem> <scriptItem id="avalon_manage"> - <label>Manage ...</label> + <label>Manage</label> <scriptCode><![CDATA[ from avalon.tools import cbsceneinventory cbsceneinventory.show() @@ -43,7 +43,7 @@ cbsceneinventory.show() </scriptItem> <scriptItem id="publish"> - <label>Publish ...</label> + <label>Publish</label> <scriptCode><![CDATA[ import hou from avalon.tools import publish From fe9729dd1848266e65da2f21f2e92d942fa35269 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:17:16 +0200 Subject: [PATCH 236/295] Nuke: removing Tab from label --- pype/hosts/nuke/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/nuke/api/lib.py b/pype/hosts/nuke/api/lib.py index a8bb08311a..dbcf571b06 100644 --- a/pype/hosts/nuke/api/lib.py +++ b/pype/hosts/nuke/api/lib.py @@ -25,7 +25,7 @@ log = Logger().get_logger(__name__) self = sys.modules[__name__] self._project = None -self._node_tab_name = "{}Tab".format(os.getenv("AVALON_LABEL") or "Avalon") +self._node_tab_name = "{}".format(os.getenv("AVALON_LABEL") or "Avalon") def get_node_imageio_setting(**kwarg): ''' Get preset data for dataflow (fileType, compression, bitDepth) From a3a91d896ba4f3f91097f36f2151bc8d925eee01 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 15:17:50 +0200 Subject: [PATCH 237/295] rename pype in startup scripts --- pype/hosts/houdini/startup/scripts/123.py | 2 +- pype/hosts/maya/startup/userSetup.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/hosts/houdini/startup/scripts/123.py b/pype/hosts/houdini/startup/scripts/123.py index 144b9fdb89..6d90b8352e 100644 --- a/pype/hosts/houdini/startup/scripts/123.py +++ b/pype/hosts/houdini/startup/scripts/123.py @@ -3,7 +3,7 @@ import hou def main(): - print("Installing Avalon ...") + print("Installing OpenPype ...") api.install(houdini) diff --git a/pype/hosts/maya/startup/userSetup.py b/pype/hosts/maya/startup/userSetup.py index a562d3ab9e..1603d4548e 100644 --- a/pype/hosts/maya/startup/userSetup.py +++ b/pype/hosts/maya/startup/userSetup.py @@ -4,7 +4,7 @@ import pype.hosts.maya.api.lib as mlib from maya import cmds -print("starting PYPE usersetup") +print("starting OpenPype usersetup") # build a shelf settings = get_project_settings(os.environ['AVALON_PROJECT']) @@ -26,4 +26,4 @@ if shelf_preset: cmds.evalDeferred("mlib.shelf(name=shelf_preset['name'], iconPath=icon_path, preset=shelf_preset)") -print("finished PYPE usersetup") +print("finished OpenPype usersetup") From 59ef7c7d05b3ddeb9211dc3e43ad51ab92068f58 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:18:03 +0200 Subject: [PATCH 238/295] Nuke: fixing menu shortcuts to be specifically OpenPype --- pype/hosts/nuke/api/menu.py | 35 +++++++++++-------- .../defaults/project_settings/nuke.json | 4 +-- .../projects_schema/schema_project_nuke.json | 11 +++--- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/pype/hosts/nuke/api/menu.py b/pype/hosts/nuke/api/menu.py index d638034809..802d17d1ed 100644 --- a/pype/hosts/nuke/api/menu.py +++ b/pype/hosts/nuke/api/menu.py @@ -1,3 +1,4 @@ +import os import nuke from avalon.api import Session @@ -7,10 +8,11 @@ from pype.tools import workfiles log = Logger().get_logger(__name__) +menu_label = os.environ["AVALON_LABEL"] def install(): menubar = nuke.menu("Nuke") - menu = menubar.findItem(Session["AVALON_LABEL"]) + menu = menubar.findItem(menu_label) # replace reset resolution from avalon core to pype's name = "Work Files..." @@ -90,7 +92,7 @@ def install(): def uninstall(): menubar = nuke.menu("Nuke") - menu = menubar.findItem(Session["AVALON_LABEL"]) + menu = menubar.findItem(menu_label) for item in menu.items(): log.info("Removing menu item: {}".format(item.name())) @@ -99,7 +101,7 @@ def uninstall(): def add_shortcuts_from_presets(): menubar = nuke.menu("Nuke") - nuke_presets = get_current_project_settings()["nuke"] + nuke_presets = get_current_project_settings()["nuke"]["general"] if nuke_presets.get("menu"): menu_label_mapping = { @@ -109,15 +111,18 @@ def add_shortcuts_from_presets(): "build_workfile": "Build Workfile", "publish": "Publish..." } - for menu_name, menuitems in nuke_presets.get("menu").items(): - menu = menubar.findItem(menu_name) - for mitem_name, shortcut in menuitems.items(): - log.info("Adding Shortcut `{}` to `{}`".format( - shortcut, mitem_name - )) - try: - item_label = menu_label_mapping[mitem_name] - menuitem = menu.findItem(item_label) - menuitem.setShortcut(shortcut) - except AttributeError as e: - log.error(e) + + for command_name, shortcut_str in nuke_presets.get("menu").items(): + log.info("menu_name `{}` | menu_label `{}`".format( + command_name, menu_label + )) + log.info("Adding Shortcut `{}` to `{}`".format( + shortcut_str, command_name + )) + try: + menu = menubar.findItem(menu_label) + item_label = menu_label_mapping[command_name] + menuitem = menu.findItem(item_label) + menuitem.setShortcut(shortcut_str) + except AttributeError as e: + log.error(e) diff --git a/pype/settings/defaults/project_settings/nuke.json b/pype/settings/defaults/project_settings/nuke.json index 71fe146b8a..0173eb0a82 100644 --- a/pype/settings/defaults/project_settings/nuke.json +++ b/pype/settings/defaults/project_settings/nuke.json @@ -1,6 +1,6 @@ { - "menu": { - "Pype": { + "general": { + "menu": { "create": "ctrl+shift+alt+c", "publish": "ctrl+alt+p", "load": "ctrl+alt+l", diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json index 3fe01cad09..75ca5411a1 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -8,15 +8,14 @@ { "type": "dict", "collapsible": true, - "key": "menu", - "label": "Menu shortcuts", + "key": "general", + "label": "General", "children": [ { "type": "dict", - "collapsible": false, - "key": "Pype", - "label": "Pype", - "is_group": true, + "collapsible": true, + "key": "menu", + "label": "OpenPype Menu shortcuts", "children": [ { "type": "text", From 531f3b180998a7653f2e2da4ea03c99d8d16433d Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:33:43 +0200 Subject: [PATCH 239/295] Resolve: fix pype3 import --- pype/hosts/resolve/api/plugin.py | 2 +- pype/hosts/resolve/plugins/create/create_shot_clip.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/hosts/resolve/api/plugin.py b/pype/hosts/resolve/api/plugin.py index 1273c9f1df..bea246ac2f 100644 --- a/pype/hosts/resolve/api/plugin.py +++ b/pype/hosts/resolve/api/plugin.py @@ -81,7 +81,7 @@ class CreatorWidget(QtWidgets.QDialog): ok_btn.clicked.connect(self._on_ok_clicked) cancel_btn.clicked.connect(self._on_cancel_clicked) - stylesheet = resolve.menu.load_stylesheet() + stylesheet = resolve.api.menu.load_stylesheet() self.setStyleSheet(stylesheet) def _on_ok_clicked(self): diff --git a/pype/hosts/resolve/plugins/create/create_shot_clip.py b/pype/hosts/resolve/plugins/create/create_shot_clip.py index 5b7dd66a25..c9bb61a9da 100644 --- a/pype/hosts/resolve/plugins/create/create_shot_clip.py +++ b/pype/hosts/resolve/plugins/create/create_shot_clip.py @@ -1,6 +1,6 @@ # from pprint import pformat from pype.hosts import resolve -from pype.hosts.resolve import lib +from pype.hosts.resolve.api import lib class CreateShotClip(resolve.Creator): @@ -244,7 +244,7 @@ class CreateShotClip(resolve.Creator): sq_markers = self.timeline.GetMarkers() # create media bin for compound clips (trackItems) - mp_folder = resolve.create_current_sequence_media_bin(self.timeline) + mp_folder = resolve.create_bin(self.timeline.GetName()) kwargs = { "ui_inputs": widget.result, From f11357de244707ddbbc263bf5bd9cc67eaade61e Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 15:44:28 +0200 Subject: [PATCH 240/295] Tweak menu for houdini --- pype/hosts/houdini/startup/MainMenuCommon.XML | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/pype/hosts/houdini/startup/MainMenuCommon.XML b/pype/hosts/houdini/startup/MainMenuCommon.XML index d1374cf7a3..faa811de86 100644 --- a/pype/hosts/houdini/startup/MainMenuCommon.XML +++ b/pype/hosts/houdini/startup/MainMenuCommon.XML @@ -3,23 +3,9 @@ <menuBar> <subMenu id="avalon_menu"> <label>OpenPype</label> - <subMenu id="avalon_context"> - <labelExpression><![CDATA[ -from avalon import api -return "%s - %s" % (api.Session["AVALON_ASSET"], api.Session["AVALON_TASK"]) -]]></labelExpression> - <scriptItem id="avalon_context_switch"> - <label>Set Context</label> - <scriptCode><![CDATA[ -from avalon.tools import contextmanager; contextmanager.show() -]]></scriptCode> - </scriptItem> - </subMenu> - - <separatorItem/> <scriptItem id="avalon_create"> - <label>Create</label> + <label>Create ...</label> <scriptCode><![CDATA[ from avalon.tools import creator creator.show() @@ -27,7 +13,7 @@ creator.show() </scriptItem> <scriptItem id="avalon_load"> - <label>Load</label> + <label>Load ...</label> <scriptCode><![CDATA[ from avalon.tools import cbloader cbloader.show(use_context=True) @@ -35,7 +21,7 @@ cbloader.show(use_context=True) </scriptItem> <scriptItem id="avalon_manage"> - <label>Manage</label> + <label>Manage ...</label> <scriptCode><![CDATA[ from avalon.tools import cbsceneinventory cbsceneinventory.show() @@ -43,7 +29,7 @@ cbsceneinventory.show() </scriptItem> <scriptItem id="publish"> - <label>Publish</label> + <label>Publish ...</label> <scriptCode><![CDATA[ import hou from avalon.tools import publish @@ -55,7 +41,7 @@ publish.show(parent) <separatorItem/> <scriptItem id="workfiles"> - <label>Work Files</label> + <label>Work Files ...</label> <scriptCode><![CDATA[ import hou, os from pype.tools import workfiles From d33476b724f09b834abe50ec588834ad6dad3444 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 15:45:16 +0200 Subject: [PATCH 241/295] changed pype prefix in hosts --- .../hooks/pre_celaction_registers.py | 2 +- pype/hosts/harmony/api/__init__.py | 2 +- .../hosts/harmony/js/creators/CreateRender.js | 4 +- .../harmony/js/loaders/ImageSequenceLoader.js | 4 +- .../harmony/js/loaders/TemplateLoader.js | 4 +- .../harmony/js/publish/CollectCurrentFile.js | 4 +- .../harmony/js/publish/CollectFarmRender.js | 4 +- .../harmony/js/publish/CollectPalettes.js | 4 +- .../harmony/js/publish/ExtractPalette.js | 4 +- .../harmony/js/publish/ExtractTemplate.js | 4 +- pype/hosts/maya/api/menu.json | 174 ++++----- pype/hosts/maya/api/menu.py | 2 +- pype/hosts/maya/api/menu_backup.json | 332 +++++++++--------- .../maya/plugins/create/create_render.py | 6 +- .../maya/plugins/create/create_vrayscene.py | 6 +- .../plugins/publish/submit_maya_muster.py | 6 +- .../publish/validate_muster_connection.py | 6 +- pype/hosts/maya/startup/userSetup.py | 2 +- pype/hosts/premiere/lib.py | 2 +- .../premiere/ppro/js/pype_restapi_client.js | 2 +- pype/hosts/unreal/api/lib.py | 10 +- 21 files changed, 292 insertions(+), 292 deletions(-) diff --git a/pype/hosts/celaction/hooks/pre_celaction_registers.py b/pype/hosts/celaction/hooks/pre_celaction_registers.py index 40e8eaa6ff..2e535d6d77 100644 --- a/pype/hosts/celaction/hooks/pre_celaction_registers.py +++ b/pype/hosts/celaction/hooks/pre_celaction_registers.py @@ -35,7 +35,7 @@ class CelactionPrelaunchHook(PreLaunchHook): winreg.KEY_ALL_ACCESS) # TODO: this will need to be checked more thoroughly - pype_exe = os.getenv("PYPE_EXECUTABLE") + pype_exe = os.getenv("OPENPYPE_EXECUTABLE") winreg.SetValueEx(hKey, "SubmitAppTitle", 0, winreg.REG_SZ, pype_exe) diff --git a/pype/hosts/harmony/api/__init__.py b/pype/hosts/harmony/api/__init__.py index 1a0255d045..ae1450d9cc 100644 --- a/pype/hosts/harmony/api/__init__.py +++ b/pype/hosts/harmony/api/__init__.py @@ -154,7 +154,7 @@ def application_launch(): # It is now moved so it it manually called. # ensure_scene_settings() # check_inventory() - # fills PYPE_HARMONY_JS + # fills OPENPYPE_HARMONY_JS pype_harmony_path = Path(__file__).parent.parent / "js" / "PypeHarmony.js" pype_harmony_js = pype_harmony_path.read_text() diff --git a/pype/hosts/harmony/js/creators/CreateRender.js b/pype/hosts/harmony/js/creators/CreateRender.js index cfb0701df4..92ec6dfd2f 100644 --- a/pype/hosts/harmony/js/creators/CreateRender.js +++ b/pype/hosts/harmony/js/creators/CreateRender.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } diff --git a/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js b/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js index cfa71e2834..d809c350ab 100644 --- a/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js +++ b/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js @@ -5,8 +5,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } if (typeof $ === 'undefined'){ diff --git a/pype/hosts/harmony/js/loaders/TemplateLoader.js b/pype/hosts/harmony/js/loaders/TemplateLoader.js index 160979f943..1df04c8282 100644 --- a/pype/hosts/harmony/js/loaders/TemplateLoader.js +++ b/pype/hosts/harmony/js/loaders/TemplateLoader.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } if (typeof $ === 'undefined'){ diff --git a/pype/hosts/harmony/js/publish/CollectCurrentFile.js b/pype/hosts/harmony/js/publish/CollectCurrentFile.js index d39f23712d..2eeb7fb764 100644 --- a/pype/hosts/harmony/js/publish/CollectCurrentFile.js +++ b/pype/hosts/harmony/js/publish/CollectCurrentFile.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } diff --git a/pype/hosts/harmony/js/publish/CollectFarmRender.js b/pype/hosts/harmony/js/publish/CollectFarmRender.js index 7c0cda5165..759dc5ce5d 100644 --- a/pype/hosts/harmony/js/publish/CollectFarmRender.js +++ b/pype/hosts/harmony/js/publish/CollectFarmRender.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } diff --git a/pype/hosts/harmony/js/publish/CollectPalettes.js b/pype/hosts/harmony/js/publish/CollectPalettes.js index 8fda55ff75..afb0ad854a 100644 --- a/pype/hosts/harmony/js/publish/CollectPalettes.js +++ b/pype/hosts/harmony/js/publish/CollectPalettes.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } diff --git a/pype/hosts/harmony/js/publish/ExtractPalette.js b/pype/hosts/harmony/js/publish/ExtractPalette.js index 794c6fdbb1..c4765354c4 100644 --- a/pype/hosts/harmony/js/publish/ExtractPalette.js +++ b/pype/hosts/harmony/js/publish/ExtractPalette.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } /** diff --git a/pype/hosts/harmony/js/publish/ExtractTemplate.js b/pype/hosts/harmony/js/publish/ExtractTemplate.js index d36a8947f8..4676e1ff68 100644 --- a/pype/hosts/harmony/js/publish/ExtractTemplate.js +++ b/pype/hosts/harmony/js/publish/ExtractTemplate.js @@ -6,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony === 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS') + '/PypeHarmony.js'; - include(PYPE_HARMONY_JS.replace(/\\/g, "/")); + var OPENPYPE_HARMONY_JS = System.getenv('OPENPYPE_HARMONY_JS') + '/PypeHarmony.js'; + include(OPENPYPE_HARMONY_JS.replace(/\\/g, "/")); } diff --git a/pype/hosts/maya/api/menu.json b/pype/hosts/maya/api/menu.json index 03eb05e5bd..b32f295ec4 100644 --- a/pype/hosts/maya/api/menu.json +++ b/pype/hosts/maya/api/menu.json @@ -1,21 +1,21 @@ [ { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\save_scene_incremental.py", + "command": "$OPENPYPE_SCRIPTS\\others\\save_scene_incremental.py", "sourcetype": "file", "title": "# Version Up", "tooltip": "Incremental save with a specific format" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\open_current_folder.py", + "command": "$OPENPYPE_SCRIPTS\\others\\open_current_folder.py", "sourcetype": "file", "title": "Open working folder..", "tooltip": "Show current scene in Explorer" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\avalon\\launch_manager.py", + "command": "$OPENPYPE_SCRIPTS\\avalon\\launch_manager.py", "sourcetype": "file", "title": "# Project Manager", "tooltip": "Add assets to the project" @@ -44,7 +44,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\separateMeshPerShader.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\separateMeshPerShader.py", "sourcetype": "file", "tags": ["modeling", "separateMeshPerShader"], "title": "# Separate Mesh Per Shader", @@ -52,7 +52,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polyDetachSeparate.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polyDetachSeparate.py", "sourcetype": "file", "tags": ["modeling", "poly", "detach", "separate"], "title": "# Polygon Detach and Separate", @@ -60,14 +60,14 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polySelectEveryNthEdgeUI.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polySelectEveryNthEdgeUI.py", "sourcetype": "file", "tags": ["modeling", "select", "nth", "edge", "ui"], "title": "# Select Every Nth Edge" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\djPFXUVs.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\djPFXUVs.py", "sourcetype": "file", "tags": ["modeling", "djPFX", "UVs"], "title": "# dj PFX UVs", @@ -81,7 +81,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\advancedSkeleton.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\advancedSkeleton.py", "sourcetype": "file", "tags": [ "rigging", @@ -106,7 +106,7 @@ { "type": "action", "title": "# Import Proxies", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayImportProxies.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayImportProxies.py", "sourcetype": "file", "tags": ["shading", "vray", "import", "proxies"], "tooltip": "" @@ -117,7 +117,7 @@ { "type": "action", "title": "# Select All GES", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectAllGES.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectAllGES.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "select All GES"] @@ -125,7 +125,7 @@ { "type": "action", "title": "# Select All GES Under Selection", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectAllGESUnderSelection.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectAllGESUnderSelection.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "select", "all", "GES"] @@ -136,7 +136,7 @@ { "type": "action", "title": "# Selection To VRay Mesh", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectionToVrayMesh.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectionToVrayMesh.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "selection", "vraymesh"] @@ -144,7 +144,7 @@ { "type": "action", "title": "# Add VRay Round Edges Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayRoundEdgesAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayRoundEdgesAttribute.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "round edges", "attribute"] @@ -152,7 +152,7 @@ { "type": "action", "title": "# Add Gamma", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayAddGamma.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayAddGamma.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "add gamma"] @@ -162,7 +162,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vray\\select_vraymesh_materials_with_unconnected_shader_slots.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\select_vraymesh_materials_with_unconnected_shader_slots.py", "sourcetype": "file", "title": "# Select Unconnected Shader Materials", "tags": [ @@ -177,7 +177,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayMergeSimilarVRayMeshMaterials.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayMergeSimilarVRayMeshMaterials.py", "sourcetype": "file", "title": "# Merge Similar VRay Mesh Materials", "tags": [ @@ -192,7 +192,7 @@ { "type": "action", "title": "# Create Two Sided Material", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtlRenamed.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtlRenamed.py", "sourcetype": "file", "tooltip": "Creates two sided material for selected material and renames it", "tags": ["shading", "vray", "two sided", "material"] @@ -200,7 +200,7 @@ { "type": "action", "title": "# Create Two Sided Material For Selected", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtl.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtl.py", "sourcetype": "file", "tooltip": "Select material to create a two sided version from it", "tags": [ @@ -215,7 +215,7 @@ { "type": "action", "title": "# Add OpenSubdiv Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayOpenSubdivAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayOpenSubdivAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -229,7 +229,7 @@ { "type": "action", "title": "# Remove OpenSubdiv Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\removeVrayOpenSubdivAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\removeVrayOpenSubdivAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -246,7 +246,7 @@ { "type": "action", "title": "# Add Subdivision Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVraySubdivisionAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVraySubdivisionAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -258,7 +258,7 @@ { "type": "action", "title": "# Remove Subdivision Attribute.py", - "command": "$PYPE_SCRIPTS\\shading\\vray\\removeVraySubdivisionAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\removeVraySubdivisionAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -275,7 +275,7 @@ { "type": "action", "title": "# Add Vray Object Ids", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayObjectIds.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayObjectIds.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "add", "object id"] @@ -283,7 +283,7 @@ { "type": "action", "title": "# Add Vray Material Ids", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayMaterialIds.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayMaterialIds.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "addVrayMaterialIds.py"] @@ -294,7 +294,7 @@ { "type": "action", "title": "# Set Physical DOF Depth", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayPhysicalDOFSetDepth.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayPhysicalDOFSetDepth.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "physical", "DOF ", "Depth"] @@ -302,7 +302,7 @@ { "type": "action", "title": "# Magic Vray Proxy UI", - "command": "$PYPE_SCRIPTS\\shading\\vray\\magicVrayProxyUI.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\magicVrayProxyUI.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "magicVrayProxyUI"] @@ -311,7 +311,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\pyblish\\lighting\\set_filename_prefix.py", + "command": "$OPENPYPE_SCRIPTS\\pyblish\\lighting\\set_filename_prefix.py", "sourcetype": "file", "tags": [ "shading", @@ -335,7 +335,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\LightLinkUi.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\LightLinkUi.py", "sourcetype": "file", "tags": ["shading", "light", "link", "ui"], "title": "# Light Link UI", @@ -343,7 +343,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vdviewer_ui.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vdviewer_ui.py", "sourcetype": "file", "tags": [ "shading", @@ -358,7 +358,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\setTexturePreviewToCLRImage.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\setTexturePreviewToCLRImage.py", "sourcetype": "file", "tags": ["shading", "CLRImage", "textures", "preview"], "title": "# Set Texture Preview To CLRImage", @@ -366,7 +366,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixDefaultShaderSetBehavior.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixDefaultShaderSetBehavior.py", "sourcetype": "file", "tags": ["shading", "fix", "DefaultShaderSet", "Behavior"], "title": "# Fix Default Shader Set Behavior", @@ -374,7 +374,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixSelectedShapesReferenceAssignments.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixSelectedShapesReferenceAssignments.py", "sourcetype": "file", "tags": [ "shading", @@ -389,7 +389,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\selectLambert1Members.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\selectLambert1Members.py", "sourcetype": "file", "tags": ["shading", "selectLambert1Members"], "title": "# Select Lambert1 Members", @@ -397,7 +397,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\selectShapesWithoutShader.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\selectShapesWithoutShader.py", "sourcetype": "file", "tags": ["shading", "selectShapesWithoutShader"], "title": "# Select Shapes Without Shader", @@ -405,7 +405,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixRenderLayerOutAdjustmentErrors.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixRenderLayerOutAdjustmentErrors.py", "sourcetype": "file", "tags": ["shading", "fixRenderLayerOutAdjustmentErrors"], "title": "# Fix RenderLayer Out Adjustment Errors", @@ -413,7 +413,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fix_renderlayer_missing_node_override.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fix_renderlayer_missing_node_override.py", "sourcetype": "file", "tags": [ "shading", @@ -429,7 +429,7 @@ { "type": "action", "title": "# Image 2 Tiled EXR", - "command": "$PYPE_SCRIPTS\\shading\\open_img2exr.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\open_img2exr.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "exr"] @@ -442,7 +442,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\pyblish\\open_deadline_submission_settings.py", + "command": "$OPENPYPE_SCRIPTS\\pyblish\\open_deadline_submission_settings.py", "sourcetype": "file", "tags": ["settings", "deadline", "globals", "render"], "title": "# DL Submission Settings UI", @@ -461,7 +461,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyValues.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyValues.py", "sourcetype": "file", "tags": ["animation", "copy", "attributes"], "title": "# Copy Values", @@ -469,7 +469,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyInConnections.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyInConnections.py", "sourcetype": "file", "tags": [ "animation", @@ -483,7 +483,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyOutConnections.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyOutConnections.py", "sourcetype": "file", "tags": [ "animation", @@ -497,7 +497,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformLocal.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformLocal.py", "sourcetype": "file", "tags": [ "animation", @@ -511,7 +511,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformMatrix.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformMatrix.py", "sourcetype": "file", "tags": [ "animation", @@ -525,7 +525,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformUI.py", "sourcetype": "file", "tags": [ "animation", @@ -539,7 +539,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\simpleCopyUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\simpleCopyUI.py", "sourcetype": "file", "tags": [ "animation", @@ -561,7 +561,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\optimize\\toggleFreezeHierarchy.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\optimize\\toggleFreezeHierarchy.py", "sourcetype": "file", "tags": ["animation", "hierarchy", "toggle", "freeze"], "title": "# Toggle Freeze Hierarchy", @@ -569,7 +569,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\optimize\\toggleParallelNucleus.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\optimize\\toggleParallelNucleus.py", "sourcetype": "file", "tags": ["animation", "nucleus", "toggle", "parallel"], "title": "# Toggle Parallel Nucleus", @@ -579,21 +579,21 @@ }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\bakeSelectedToWorldSpace.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\bakeSelectedToWorldSpace.py", "tags": ["animation", "bake", "selection", "worldspace.py"], "title": "# Bake Selected To Worldspace", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\timeStepper.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\timeStepper.py", "tags": ["animation", "time", "stepper"], "title": "# Time Stepper", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\capture_ui.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\capture_ui.py", "tags": [ "animation", "capture", @@ -607,63 +607,63 @@ }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\simplePlayblastUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\simplePlayblastUI.py", "tags": ["animation", "simple", "playblast", "ui"], "title": "# Simple Playblast UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\tweenMachineUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\tweenMachineUI.py", "tags": ["animation", "tween", "machine"], "title": "# Tween Machine UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\selectAllAnimationCurves.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\selectAllAnimationCurves.py", "tags": ["animation", "select", "curves"], "title": "# Select All Animation Curves", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\pathAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\pathAnimation.py", "tags": ["animation", "path", "along"], "title": "# Path Animation", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\offsetSelectedObjectsUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\offsetSelectedObjectsUI.py", "tags": ["animation", "offsetSelectedObjectsUI.py"], "title": "# Offset Selected Objects UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\key_amplifier_ui.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\key_amplifier_ui.py", "tags": ["animation", "key", "amplifier"], "title": "# Key Amplifier UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\anim_scene_optimizer.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\anim_scene_optimizer.py", "tags": ["animation", "anim_scene_optimizer.py"], "title": "# Anim_Scene_Optimizer", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\zvParentMaster.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\zvParentMaster.py", "tags": ["animation", "zvParentMaster.py"], "title": "# ZV Parent Master", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\animLibrary.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\animLibrary.py", "tags": ["animation", "studiolibrary.py"], "title": "Anim Library", "type": "action" @@ -676,7 +676,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\alignDistributeUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\alignDistributeUI.py", "sourcetype": "file", "tags": ["layout", "align", "Distribute", "UI"], "title": "# Align Distribute UI", @@ -684,7 +684,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\alignSimpleUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\alignSimpleUI.py", "sourcetype": "file", "tags": ["layout", "align", "UI", "Simple"], "title": "# Align Simple UI", @@ -692,7 +692,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\center_locator.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\center_locator.py", "sourcetype": "file", "tags": ["layout", "center", "locator"], "title": "# Center Locator", @@ -700,7 +700,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\average_locator.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\average_locator.py", "sourcetype": "file", "tags": ["layout", "average", "locator"], "title": "# Average Locator", @@ -708,7 +708,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\selectWithinProximityUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\selectWithinProximityUI.py", "sourcetype": "file", "tags": ["layout", "select", "proximity", "ui"], "title": "# Select Within Proximity UI", @@ -716,7 +716,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\dupCurveUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\dupCurveUI.py", "sourcetype": "file", "tags": ["layout", "Duplicate", "Curve", "UI"], "title": "# Duplicate Curve UI", @@ -724,7 +724,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\randomDeselectUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\randomDeselectUI.py", "sourcetype": "file", "tags": ["layout", "random", "Deselect", "UI"], "title": "# Random Deselect UI", @@ -732,7 +732,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\multiReferencerUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\multiReferencerUI.py", "sourcetype": "file", "tags": ["layout", "multi", "reference"], "title": "# Multi Referencer UI", @@ -740,7 +740,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\duplicateOffsetUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\duplicateOffsetUI.py", "sourcetype": "file", "tags": ["layout", "duplicate", "offset", "UI"], "title": "# Duplicate Offset UI", @@ -748,7 +748,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\spPaint3d.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\spPaint3d.py", "sourcetype": "file", "tags": ["layout", "spPaint3d", "paint", "tool"], "title": "# SP Paint 3d", @@ -756,7 +756,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\randomizeUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\randomizeUI.py", "sourcetype": "file", "tags": ["layout", "randomize", "UI"], "title": "# Randomize UI", @@ -764,7 +764,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\distributeWithinObjectUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\distributeWithinObjectUI.py", "sourcetype": "file", "tags": ["layout", "distribute", "ObjectUI", "within"], "title": "# Distribute Within Object UI", @@ -778,7 +778,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjects.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjects.py", "sourcetype": "file", "tags": ["particles", "instancerToObjects"], "title": "# Instancer To Objects", @@ -786,7 +786,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsInstances.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsInstances.py", "sourcetype": "file", "tags": ["particles", "instancerToObjectsInstances"], "title": "# Instancer To Objects Instances", @@ -794,7 +794,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsInstancesWithAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsInstancesWithAnimation.py", "sourcetype": "file", "tags": [ "particles", @@ -805,7 +805,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsWithAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsWithAnimation.py", "sourcetype": "file", "tags": ["particles", "instancerToObjectsWithAnimation"], "title": "# Instancer To Objects With Animation", @@ -819,7 +819,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\repair_faulty_containers.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\repair_faulty_containers.py", "sourcetype": "file", "tags": ["cleanup", "repair", "containers"], "title": "# Find and Repair Containers", @@ -830,7 +830,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeNamespaces.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeNamespaces.py", "sourcetype": "file", "tags": ["cleanup", "remove", "namespaces"], "title": "# Remove Namespaces", @@ -838,7 +838,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\remove_user_defined_attributes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\remove_user_defined_attributes.py", "sourcetype": "file", "tags": ["cleanup", "remove_user_defined_attributes"], "title": "# Remove User Defined Attributes", @@ -846,7 +846,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeUnknownNodes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeUnknownNodes.py", "sourcetype": "file", "tags": ["cleanup", "removeUnknownNodes"], "title": "# Remove Unknown Nodes", @@ -854,7 +854,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeUnloadedReferences.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeUnloadedReferences.py", "sourcetype": "file", "tags": ["cleanup", "removeUnloadedReferences"], "title": "# Remove Unloaded References", @@ -862,7 +862,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeReferencesFailedEdits.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeReferencesFailedEdits.py", "sourcetype": "file", "tags": ["cleanup", "removeReferencesFailedEdits"], "title": "# Remove References Failed Edits", @@ -870,7 +870,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\remove_unused_looks.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\remove_unused_looks.py", "sourcetype": "file", "tags": ["cleanup", "removeUnusedLooks"], "title": "# Remove Unused Looks", @@ -881,7 +881,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\uniqifyNodeNames.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\uniqifyNodeNames.py", "sourcetype": "file", "tags": ["cleanup", "uniqifyNodeNames"], "title": "# Uniqify Node Names", @@ -889,7 +889,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\autoRenameFileNodes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\autoRenameFileNodes.py", "sourcetype": "file", "tags": ["cleanup", "auto", "rename", "filenodes"], "title": "# Auto Rename File Nodes", @@ -897,7 +897,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\update_asset_id.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\update_asset_id.py", "sourcetype": "file", "tags": ["cleanup", "update", "database", "asset", "id"], "title": "# Update Asset ID", @@ -905,7 +905,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\ccRenameReplace.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\ccRenameReplace.py", "sourcetype": "file", "tags": ["cleanup", "rename", "ui"], "title": "Renamer", @@ -913,7 +913,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\renameShapesToTransform.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\renameShapesToTransform.py", "sourcetype": "file", "tags": ["cleanup", "renameShapesToTransform"], "title": "# Rename Shapes To Transform", diff --git a/pype/hosts/maya/api/menu.py b/pype/hosts/maya/api/menu.py index 9381043511..5993268f1d 100644 --- a/pype/hosts/maya/api/menu.py +++ b/pype/hosts/maya/api/menu.py @@ -8,7 +8,7 @@ from pype.api import BuildWorkfile import maya.cmds as cmds self = sys.modules[__name__] -self._menu = os.environ.get('PYPE_STUDIO_NAME') or "Pype" +self._menu = os.environ.get('OPENPYPE_STUDIO_NAME') or "Pype" log = logging.getLogger(__name__) diff --git a/pype/hosts/maya/api/menu_backup.json b/pype/hosts/maya/api/menu_backup.json index 735799345d..731a33a630 100644 --- a/pype/hosts/maya/api/menu_backup.json +++ b/pype/hosts/maya/api/menu_backup.json @@ -1,21 +1,21 @@ [ { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\save_scene_incremental.py", + "command": "$OPENPYPE_SCRIPTS\\others\\save_scene_incremental.py", "sourcetype": "file", "title": "Version Up", "tooltip": "Incremental save with a specific format" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\show_current_scene_in_explorer.py", + "command": "$OPENPYPE_SCRIPTS\\others\\show_current_scene_in_explorer.py", "sourcetype": "file", "title": "Explore current scene..", "tooltip": "Show current scene in Explorer" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\avalon\\launch_manager.py", + "command": "$OPENPYPE_SCRIPTS\\avalon\\launch_manager.py", "sourcetype": "file", "title": "Project Manager", "tooltip": "Add assets to the project" @@ -29,7 +29,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\duplicate_normalized.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\duplicate_normalized.py", "sourcetype": "file", "tags": ["modeling", "duplicate", "normalized"], "title": "Duplicate Normalized", @@ -37,7 +37,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\transferUVs.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\transferUVs.py", "sourcetype": "file", "tags": ["modeling", "transfer", "uv"], "title": "Transfer UVs", @@ -45,7 +45,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\mirrorSymmetry.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\mirrorSymmetry.py", "sourcetype": "file", "tags": ["modeling", "mirror", "symmetry"], "title": "Mirror Symmetry", @@ -53,7 +53,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\selectOutlineUI.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\selectOutlineUI.py", "sourcetype": "file", "tags": ["modeling", "select", "outline", "ui"], "title": "Select Outline UI", @@ -61,7 +61,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polyDeleteOtherUVSets.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polyDeleteOtherUVSets.py", "sourcetype": "file", "tags": ["modeling", "polygon", "uvset", "delete"], "title": "Polygon Delete Other UV Sets", @@ -69,7 +69,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polyCombineQuick.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polyCombineQuick.py", "sourcetype": "file", "tags": ["modeling", "combine", "polygon", "quick"], "title": "Polygon Combine Quick", @@ -77,7 +77,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\separateMeshPerShader.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\separateMeshPerShader.py", "sourcetype": "file", "tags": ["modeling", "separateMeshPerShader"], "title": "Separate Mesh Per Shader", @@ -85,7 +85,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polyDetachSeparate.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polyDetachSeparate.py", "sourcetype": "file", "tags": ["modeling", "poly", "detach", "separate"], "title": "Polygon Detach and Separate", @@ -93,7 +93,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polyRelaxVerts.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polyRelaxVerts.py", "sourcetype": "file", "tags": ["modeling", "relax", "verts"], "title": "Polygon Relax Vertices", @@ -101,14 +101,14 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\polySelectEveryNthEdgeUI.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\polySelectEveryNthEdgeUI.py", "sourcetype": "file", "tags": ["modeling", "select", "nth", "edge", "ui"], "title": "Select Every Nth Edge" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\modeling\\djPFXUVs.py", + "command": "$OPENPYPE_SCRIPTS\\modeling\\djPFXUVs.py", "sourcetype": "file", "tags": ["modeling", "djPFX", "UVs"], "title": "dj PFX UVs", @@ -122,105 +122,105 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\addCurveBetween.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\addCurveBetween.py", "sourcetype": "file", "tags": ["rigging", "addCurveBetween", "file"], "title": "Add Curve Between" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\averageSkinWeights.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\averageSkinWeights.py", "sourcetype": "file", "tags": ["rigging", "average", "skin weights", "file"], "title": "Average Skin Weights" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\cbSmoothSkinWeightUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\cbSmoothSkinWeightUI.py", "sourcetype": "file", "tags": ["rigging", "cbSmoothSkinWeightUI", "file"], "title": "CB Smooth Skin Weight UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\channelBoxManagerUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\channelBoxManagerUI.py", "sourcetype": "file", "tags": ["rigging", "channelBoxManagerUI", "file"], "title": "Channel Box Manager UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\characterAutorigger.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\characterAutorigger.py", "sourcetype": "file", "tags": ["rigging", "characterAutorigger", "file"], "title": "Character Auto Rigger" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\connectUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\connectUI.py", "sourcetype": "file", "tags": ["rigging", "connectUI", "file"], "title": "Connect UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\copySkinWeightsLocal.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\copySkinWeightsLocal.py", "sourcetype": "file", "tags": ["rigging", "copySkinWeightsLocal", "file"], "title": "Copy Skin Weights Local" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\createCenterLocator.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\createCenterLocator.py", "sourcetype": "file", "tags": ["rigging", "createCenterLocator", "file"], "title": "Create Center Locator" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\freezeTransformToGroup.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\freezeTransformToGroup.py", "sourcetype": "file", "tags": ["rigging", "freezeTransformToGroup", "file"], "title": "Freeze Transform To Group" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\groupSelected.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\groupSelected.py", "sourcetype": "file", "tags": ["rigging", "groupSelected", "file"], "title": "Group Selected" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\ikHandlePoleVectorLocator.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\ikHandlePoleVectorLocator.py", "sourcetype": "file", "tags": ["rigging", "ikHandlePoleVectorLocator", "file"], "title": "IK Handle Pole Vector Locator" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\jointOrientUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\jointOrientUI.py", "sourcetype": "file", "tags": ["rigging", "jointOrientUI", "file"], "title": "Joint Orient UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\jointsOnCurve.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\jointsOnCurve.py", "sourcetype": "file", "tags": ["rigging", "jointsOnCurve", "file"], "title": "Joints On Curve" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\resetBindSelectedSkinJoints.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\resetBindSelectedSkinJoints.py", "sourcetype": "file", "tags": ["rigging", "resetBindSelectedSkinJoints", "file"], "title": "Reset Bind Selected Skin Joints" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\selectSkinclusterJointsFromSelectedComponents.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\selectSkinclusterJointsFromSelectedComponents.py", "sourcetype": "file", "tags": [ "rigging", @@ -231,7 +231,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\selectSkinclusterJointsFromSelectedMesh.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\selectSkinclusterJointsFromSelectedMesh.py", "sourcetype": "file", "tags": [ "rigging", @@ -242,14 +242,14 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\setJointLabels.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\setJointLabels.py", "sourcetype": "file", "tags": ["rigging", "setJointLabels", "file"], "title": "Set Joint Labels" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\setJointOrientationFromCurrentRotation.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\setJointOrientationFromCurrentRotation.py", "sourcetype": "file", "tags": [ "rigging", @@ -260,84 +260,84 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\setSelectedJointsOrientationZero.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\setSelectedJointsOrientationZero.py", "sourcetype": "file", "tags": ["rigging", "setSelectedJointsOrientationZero", "file"], "title": "Set Selected Joints Orientation Zero" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\mirrorCurveShape.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\mirrorCurveShape.py", "sourcetype": "file", "tags": ["rigging", "mirrorCurveShape", "file"], "title": "Mirror Curve Shape" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\setRotationOrderUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\setRotationOrderUI.py", "sourcetype": "file", "tags": ["rigging", "setRotationOrderUI", "file"], "title": "Set Rotation Order UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\paintItNowUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\paintItNowUI.py", "sourcetype": "file", "tags": ["rigging", "paintItNowUI", "file"], "title": "Paint It Now UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\parentScaleConstraint.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\parentScaleConstraint.py", "sourcetype": "file", "tags": ["rigging", "parentScaleConstraint", "file"], "title": "Parent Scale Constraint" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\quickSetWeightsUI.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\quickSetWeightsUI.py", "sourcetype": "file", "tags": ["rigging", "quickSetWeightsUI", "file"], "title": "Quick Set Weights UI" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\rapidRig.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\rapidRig.py", "sourcetype": "file", "tags": ["rigging", "rapidRig", "file"], "title": "Rapid Rig" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\regenerate_blendshape_targets.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\regenerate_blendshape_targets.py", "sourcetype": "file", "tags": ["rigging", "regenerate_blendshape_targets", "file"], "title": "Regenerate Blendshape Targets" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\removeRotationAxis.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\removeRotationAxis.py", "sourcetype": "file", "tags": ["rigging", "removeRotationAxis", "file"], "title": "Remove Rotation Axis" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\resetBindSelectedMeshes.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\resetBindSelectedMeshes.py", "sourcetype": "file", "tags": ["rigging", "resetBindSelectedMeshes", "file"], "title": "Reset Bind Selected Meshes" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\simpleControllerOnSelection.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\simpleControllerOnSelection.py", "sourcetype": "file", "tags": ["rigging", "simpleControllerOnSelection", "file"], "title": "Simple Controller On Selection" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\simpleControllerOnSelectionHierarchy.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\simpleControllerOnSelectionHierarchy.py", "sourcetype": "file", "tags": [ "rigging", @@ -348,35 +348,35 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\superRelativeCluster.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\superRelativeCluster.py", "sourcetype": "file", "tags": ["rigging", "superRelativeCluster", "file"], "title": "Super Relative Cluster" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\tfSmoothSkinWeight.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\tfSmoothSkinWeight.py", "sourcetype": "file", "tags": ["rigging", "tfSmoothSkinWeight", "file"], "title": "TF Smooth Skin Weight" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\toggleIntermediates.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\toggleIntermediates.py", "sourcetype": "file", "tags": ["rigging", "toggleIntermediates", "file"], "title": "Toggle Intermediates" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\toggleSegmentScaleCompensate.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\toggleSegmentScaleCompensate.py", "sourcetype": "file", "tags": ["rigging", "toggleSegmentScaleCompensate", "file"], "title": "Toggle Segment Scale Compensate" }, { "type": "action", - "command": "$PYPE_SCRIPTS\\rigging\\toggleSkinclusterDeformNormals.py", + "command": "$OPENPYPE_SCRIPTS\\rigging\\toggleSkinclusterDeformNormals.py", "sourcetype": "file", "tags": ["rigging", "toggleSkinclusterDeformNormals", "file"], "title": "Toggle Skincluster Deform Normals" @@ -394,7 +394,7 @@ { "type": "action", "title": "Import Proxies", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayImportProxies.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayImportProxies.py", "sourcetype": "file", "tags": ["shading", "vray", "import", "proxies"], "tooltip": "" @@ -405,7 +405,7 @@ { "type": "action", "title": "Select All GES", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectAllGES.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectAllGES.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "select All GES"] @@ -413,7 +413,7 @@ { "type": "action", "title": "Select All GES Under Selection", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectAllGESUnderSelection.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectAllGESUnderSelection.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "select", "all", "GES"] @@ -424,7 +424,7 @@ { "type": "action", "title": "Selection To VRay Mesh", - "command": "$PYPE_SCRIPTS\\shading\\vray\\selectionToVrayMesh.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\selectionToVrayMesh.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "selection", "vraymesh"] @@ -432,7 +432,7 @@ { "type": "action", "title": "Add VRay Round Edges Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayRoundEdgesAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayRoundEdgesAttribute.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "round edges", "attribute"] @@ -440,7 +440,7 @@ { "type": "action", "title": "Add Gamma", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayAddGamma.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayAddGamma.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "add gamma"] @@ -450,7 +450,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vray\\select_vraymesh_materials_with_unconnected_shader_slots.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\select_vraymesh_materials_with_unconnected_shader_slots.py", "sourcetype": "file", "title": "Select Unconnected Shader Materials", "tags": [ @@ -465,7 +465,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayMergeSimilarVRayMeshMaterials.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayMergeSimilarVRayMeshMaterials.py", "sourcetype": "file", "title": "Merge Similar VRay Mesh Materials", "tags": [ @@ -480,7 +480,7 @@ { "type": "action", "title": "Create Two Sided Material", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtlRenamed.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtlRenamed.py", "sourcetype": "file", "tooltip": "Creates two sided material for selected material and renames it", "tags": ["shading", "vray", "two sided", "material"] @@ -488,7 +488,7 @@ { "type": "action", "title": "Create Two Sided Material For Selected", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtl.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayCreate2SidedMtlForSelectedMtl.py", "sourcetype": "file", "tooltip": "Select material to create a two sided version from it", "tags": [ @@ -503,7 +503,7 @@ { "type": "action", "title": "Add OpenSubdiv Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayOpenSubdivAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayOpenSubdivAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -517,7 +517,7 @@ { "type": "action", "title": "Remove OpenSubdiv Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\removeVrayOpenSubdivAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\removeVrayOpenSubdivAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -534,7 +534,7 @@ { "type": "action", "title": "Add Subdivision Attribute", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVraySubdivisionAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVraySubdivisionAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -546,7 +546,7 @@ { "type": "action", "title": "Remove Subdivision Attribute.py", - "command": "$PYPE_SCRIPTS\\shading\\vray\\removeVraySubdivisionAttribute.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\removeVraySubdivisionAttribute.py", "sourcetype": "file", "tooltip": "", "tags": [ @@ -563,7 +563,7 @@ { "type": "action", "title": "Add Vray Object Ids", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayObjectIds.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayObjectIds.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "add", "object id"] @@ -571,7 +571,7 @@ { "type": "action", "title": "Add Vray Material Ids", - "command": "$PYPE_SCRIPTS\\shading\\vray\\addVrayMaterialIds.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\addVrayMaterialIds.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "addVrayMaterialIds.py"] @@ -582,7 +582,7 @@ { "type": "action", "title": "Set Physical DOF Depth", - "command": "$PYPE_SCRIPTS\\shading\\vray\\vrayPhysicalDOFSetDepth.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\vrayPhysicalDOFSetDepth.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "physical", "DOF ", "Depth"] @@ -590,7 +590,7 @@ { "type": "action", "title": "Magic Vray Proxy UI", - "command": "$PYPE_SCRIPTS\\shading\\vray\\magicVrayProxyUI.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vray\\magicVrayProxyUI.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "magicVrayProxyUI"] @@ -599,7 +599,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\pyblish\\lighting\\set_filename_prefix.py", + "command": "$OPENPYPE_SCRIPTS\\pyblish\\lighting\\set_filename_prefix.py", "sourcetype": "file", "tags": [ "shading", @@ -623,7 +623,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\LightLinkUi.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\LightLinkUi.py", "sourcetype": "file", "tags": ["shading", "light", "link", "ui"], "title": "Light Link UI", @@ -631,7 +631,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\vdviewer_ui.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\vdviewer_ui.py", "sourcetype": "file", "tags": [ "shading", @@ -646,7 +646,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\setTexturePreviewToCLRImage.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\setTexturePreviewToCLRImage.py", "sourcetype": "file", "tags": ["shading", "CLRImage", "textures", "preview"], "title": "Set Texture Preview To CLRImage", @@ -654,7 +654,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixDefaultShaderSetBehavior.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixDefaultShaderSetBehavior.py", "sourcetype": "file", "tags": ["shading", "fix", "DefaultShaderSet", "Behavior"], "title": "Fix Default Shader Set Behavior", @@ -662,7 +662,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixSelectedShapesReferenceAssignments.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixSelectedShapesReferenceAssignments.py", "sourcetype": "file", "tags": [ "shading", @@ -677,7 +677,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\selectLambert1Members.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\selectLambert1Members.py", "sourcetype": "file", "tags": ["shading", "selectLambert1Members"], "title": "Select Lambert1 Members", @@ -685,7 +685,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\selectShapesWithoutShader.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\selectShapesWithoutShader.py", "sourcetype": "file", "tags": ["shading", "selectShapesWithoutShader"], "title": "Select Shapes Without Shader", @@ -693,7 +693,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fixRenderLayerOutAdjustmentErrors.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fixRenderLayerOutAdjustmentErrors.py", "sourcetype": "file", "tags": ["shading", "fixRenderLayerOutAdjustmentErrors"], "title": "Fix RenderLayer Out Adjustment Errors", @@ -701,7 +701,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\shading\\fix_renderlayer_missing_node_override.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\fix_renderlayer_missing_node_override.py", "sourcetype": "file", "tags": [ "shading", @@ -717,7 +717,7 @@ { "type": "action", "title": "Image 2 Tiled EXR", - "command": "$PYPE_SCRIPTS\\shading\\open_img2exr.py", + "command": "$OPENPYPE_SCRIPTS\\shading\\open_img2exr.py", "sourcetype": "file", "tooltip": "", "tags": ["shading", "vray", "exr"] @@ -730,7 +730,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\pyblish\\open_deadline_submission_settings.py", + "command": "$OPENPYPE_SCRIPTS\\pyblish\\open_deadline_submission_settings.py", "sourcetype": "file", "tags": ["settings", "deadline", "globals", "render"], "title": "DL Submission Settings UI", @@ -749,7 +749,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyValues.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyValues.py", "sourcetype": "file", "tags": ["animation", "copy", "attributes"], "title": "Copy Values", @@ -757,7 +757,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyInConnections.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyInConnections.py", "sourcetype": "file", "tags": [ "animation", @@ -771,7 +771,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyOutConnections.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyOutConnections.py", "sourcetype": "file", "tags": [ "animation", @@ -785,7 +785,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformLocal.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformLocal.py", "sourcetype": "file", "tags": [ "animation", @@ -799,7 +799,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformMatrix.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformMatrix.py", "sourcetype": "file", "tags": [ "animation", @@ -813,7 +813,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\copyTransformUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\copyTransformUI.py", "sourcetype": "file", "tags": [ "animation", @@ -827,7 +827,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\attributes\\simpleCopyUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\attributes\\simpleCopyUI.py", "sourcetype": "file", "tags": [ "animation", @@ -849,7 +849,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\optimize\\toggleFreezeHierarchy.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\optimize\\toggleFreezeHierarchy.py", "sourcetype": "file", "tags": ["animation", "hierarchy", "toggle", "freeze"], "title": "Toggle Freeze Hierarchy", @@ -857,7 +857,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\animation\\optimize\\toggleParallelNucleus.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\optimize\\toggleParallelNucleus.py", "sourcetype": "file", "tags": ["animation", "nucleus", "toggle", "parallel"], "title": "Toggle Parallel Nucleus", @@ -867,21 +867,21 @@ }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\bakeSelectedToWorldSpace.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\bakeSelectedToWorldSpace.py", "tags": ["animation", "bake", "selection", "worldspace.py"], "title": "Bake Selected To Worldspace", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\timeStepper.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\timeStepper.py", "tags": ["animation", "time", "stepper"], "title": "Time Stepper", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\capture_ui.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\capture_ui.py", "tags": [ "animation", "capture", @@ -895,63 +895,63 @@ }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\simplePlayblastUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\simplePlayblastUI.py", "tags": ["animation", "simple", "playblast", "ui"], "title": "Simple Playblast UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\tweenMachineUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\tweenMachineUI.py", "tags": ["animation", "tween", "machine"], "title": "Tween Machine UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\selectAllAnimationCurves.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\selectAllAnimationCurves.py", "tags": ["animation", "select", "curves"], "title": "Select All Animation Curves", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\pathAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\pathAnimation.py", "tags": ["animation", "path", "along"], "title": "Path Animation", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\offsetSelectedObjectsUI.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\offsetSelectedObjectsUI.py", "tags": ["animation", "offsetSelectedObjectsUI.py"], "title": "Offset Selected Objects UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\key_amplifier_ui.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\key_amplifier_ui.py", "tags": ["animation", "key", "amplifier"], "title": "Key Amplifier UI", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\anim_scene_optimizer.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\anim_scene_optimizer.py", "tags": ["animation", "anim_scene_optimizer.py"], "title": "Anim_Scene_Optimizer", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\zvParentMaster.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\zvParentMaster.py", "tags": ["animation", "zvParentMaster.py"], "title": "ZV Parent Master", "type": "action" }, { "sourcetype": "file", - "command": "$PYPE_SCRIPTS\\animation\\poseLibrary.py", + "command": "$OPENPYPE_SCRIPTS\\animation\\poseLibrary.py", "tags": ["animation", "poseLibrary.py"], "title": "Pose Library", "type": "action" @@ -964,7 +964,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\alignDistributeUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\alignDistributeUI.py", "sourcetype": "file", "tags": ["layout", "align", "Distribute", "UI"], "title": "Align Distribute UI", @@ -972,7 +972,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\alignSimpleUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\alignSimpleUI.py", "sourcetype": "file", "tags": ["layout", "align", "UI", "Simple"], "title": "Align Simple UI", @@ -980,7 +980,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\center_locator.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\center_locator.py", "sourcetype": "file", "tags": ["layout", "center", "locator"], "title": "Center Locator", @@ -988,7 +988,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\average_locator.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\average_locator.py", "sourcetype": "file", "tags": ["layout", "average", "locator"], "title": "Average Locator", @@ -996,7 +996,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\selectWithinProximityUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\selectWithinProximityUI.py", "sourcetype": "file", "tags": ["layout", "select", "proximity", "ui"], "title": "Select Within Proximity UI", @@ -1004,7 +1004,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\dupCurveUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\dupCurveUI.py", "sourcetype": "file", "tags": ["layout", "Duplicate", "Curve", "UI"], "title": "Duplicate Curve UI", @@ -1012,7 +1012,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\randomDeselectUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\randomDeselectUI.py", "sourcetype": "file", "tags": ["layout", "random", "Deselect", "UI"], "title": "Random Deselect UI", @@ -1020,7 +1020,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\multiReferencerUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\multiReferencerUI.py", "sourcetype": "file", "tags": ["layout", "multi", "reference"], "title": "Multi Referencer UI", @@ -1028,7 +1028,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\duplicateOffsetUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\duplicateOffsetUI.py", "sourcetype": "file", "tags": ["layout", "duplicate", "offset", "UI"], "title": "Duplicate Offset UI", @@ -1036,7 +1036,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\spPaint3d.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\spPaint3d.py", "sourcetype": "file", "tags": ["layout", "spPaint3d", "paint", "tool"], "title": "SP Paint 3d", @@ -1044,7 +1044,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\randomizeUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\randomizeUI.py", "sourcetype": "file", "tags": ["layout", "randomize", "UI"], "title": "Randomize UI", @@ -1052,7 +1052,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\layout\\distributeWithinObjectUI.py", + "command": "$OPENPYPE_SCRIPTS\\layout\\distributeWithinObjectUI.py", "sourcetype": "file", "tags": ["layout", "distribute", "ObjectUI", "within"], "title": "Distribute Within Object UI", @@ -1066,7 +1066,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjects.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjects.py", "sourcetype": "file", "tags": ["particles", "instancerToObjects"], "title": "Instancer To Objects", @@ -1074,7 +1074,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsInstances.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsInstances.py", "sourcetype": "file", "tags": ["particles", "instancerToObjectsInstances"], "title": "Instancer To Objects Instances", @@ -1082,7 +1082,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\objectsToParticlesAndInstancerCleanSource.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\objectsToParticlesAndInstancerCleanSource.py", "sourcetype": "file", "tags": [ "particles", @@ -1097,7 +1097,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\particleComponentsToLocators.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\particleComponentsToLocators.py", "sourcetype": "file", "tags": ["particles", "components", "locators"], "title": "Particle Components To Locators", @@ -1105,7 +1105,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\objectsToParticlesAndInstancer.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\objectsToParticlesAndInstancer.py", "sourcetype": "file", "tags": ["particles", "objects", "particles", "instancer"], "title": "Objects To Particles And Instancer", @@ -1113,7 +1113,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\spawnParticlesOnMesh.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\spawnParticlesOnMesh.py", "sourcetype": "file", "tags": ["particles", "spawn", "on", "mesh"], "title": "Spawn Particles On Mesh", @@ -1121,7 +1121,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsInstancesWithAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsInstancesWithAnimation.py", "sourcetype": "file", "tags": [ "particles", @@ -1132,7 +1132,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\objectsToParticles.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\objectsToParticles.py", "sourcetype": "file", "tags": ["particles", "objectsToParticles"], "title": "Objects To Particles", @@ -1140,7 +1140,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\add_particle_cacheFile_attrs.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\add_particle_cacheFile_attrs.py", "sourcetype": "file", "tags": ["particles", "add_particle_cacheFile_attrs"], "title": "Add Particle CacheFile Attributes", @@ -1148,7 +1148,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\mergeParticleSystems.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\mergeParticleSystems.py", "sourcetype": "file", "tags": ["particles", "mergeParticleSystems"], "title": "Merge Particle Systems", @@ -1156,7 +1156,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\particlesToLocators.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\particlesToLocators.py", "sourcetype": "file", "tags": ["particles", "particlesToLocators"], "title": "Particles To Locators", @@ -1164,7 +1164,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\instancerToObjectsWithAnimation.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\instancerToObjectsWithAnimation.py", "sourcetype": "file", "tags": ["particles", "instancerToObjectsWithAnimation"], "title": "Instancer To Objects With Animation", @@ -1175,7 +1175,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\mayaReplicateHoudiniTool.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\mayaReplicateHoudiniTool.py", "sourcetype": "file", "tags": [ "particles", @@ -1191,7 +1191,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\clearInitialState.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\clearInitialState.py", "sourcetype": "file", "tags": ["particles", "clearInitialState"], "title": "Clear Initial State", @@ -1199,7 +1199,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\particles\\killSelectedParticles.py", + "command": "$OPENPYPE_SCRIPTS\\particles\\killSelectedParticles.py", "sourcetype": "file", "tags": ["particles", "killSelectedParticles"], "title": "Kill Selected Particles", @@ -1213,7 +1213,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\yeti\\yeti_rig_manager.py", + "command": "$OPENPYPE_SCRIPTS\\yeti\\yeti_rig_manager.py", "sourcetype": "file", "tags": ["yeti", "rig", "fur", "manager"], "title": "Open Yeti Rig Manager", @@ -1227,7 +1227,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\repair_faulty_containers.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\repair_faulty_containers.py", "sourcetype": "file", "tags": ["cleanup", "repair", "containers"], "title": "Find and Repair Containers", @@ -1235,7 +1235,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\selectByType.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\selectByType.py", "sourcetype": "file", "tags": ["cleanup", "selectByType"], "title": "Select By Type", @@ -1243,7 +1243,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\selectIntermediateObjects.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\selectIntermediateObjects.py", "sourcetype": "file", "tags": ["cleanup", "selectIntermediateObjects"], "title": "Select Intermediate Objects", @@ -1251,7 +1251,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\selectNonUniqueNames.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\selectNonUniqueNames.py", "sourcetype": "file", "tags": ["cleanup", "select", "non unique", "names"], "title": "Select Non Unique Names", @@ -1262,7 +1262,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeNamespaces.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeNamespaces.py", "sourcetype": "file", "tags": ["cleanup", "remove", "namespaces"], "title": "Remove Namespaces", @@ -1270,7 +1270,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\remove_user_defined_attributes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\remove_user_defined_attributes.py", "sourcetype": "file", "tags": ["cleanup", "remove_user_defined_attributes"], "title": "Remove User Defined Attributes", @@ -1278,7 +1278,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeUnknownNodes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeUnknownNodes.py", "sourcetype": "file", "tags": ["cleanup", "removeUnknownNodes"], "title": "Remove Unknown Nodes", @@ -1286,7 +1286,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeUnloadedReferences.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeUnloadedReferences.py", "sourcetype": "file", "tags": ["cleanup", "removeUnloadedReferences"], "title": "Remove Unloaded References", @@ -1294,7 +1294,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\removeReferencesFailedEdits.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\removeReferencesFailedEdits.py", "sourcetype": "file", "tags": ["cleanup", "removeReferencesFailedEdits"], "title": "Remove References Failed Edits", @@ -1302,7 +1302,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\remove_unused_looks.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\remove_unused_looks.py", "sourcetype": "file", "tags": ["cleanup", "removeUnusedLooks"], "title": "Remove Unused Looks", @@ -1310,7 +1310,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\deleteGhostIntermediateObjects.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\deleteGhostIntermediateObjects.py", "sourcetype": "file", "tags": ["cleanup", "deleteGhostIntermediateObjects"], "title": "Delete Ghost Intermediate Objects", @@ -1321,7 +1321,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\resetViewportCache.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\resetViewportCache.py", "sourcetype": "file", "tags": ["cleanup", "reset", "viewport", "cache"], "title": "Reset Viewport Cache", @@ -1329,7 +1329,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\uniqifyNodeNames.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\uniqifyNodeNames.py", "sourcetype": "file", "tags": ["cleanup", "uniqifyNodeNames"], "title": "Uniqify Node Names", @@ -1337,7 +1337,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\autoRenameFileNodes.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\autoRenameFileNodes.py", "sourcetype": "file", "tags": ["cleanup", "auto", "rename", "filenodes"], "title": "Auto Rename File Nodes", @@ -1345,7 +1345,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\update_asset_id.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\update_asset_id.py", "sourcetype": "file", "tags": ["cleanup", "update", "database", "asset", "id"], "title": "Update Asset ID", @@ -1353,7 +1353,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\colorbleedRename.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\colorbleedRename.py", "sourcetype": "file", "tags": ["cleanup", "rename", "ui"], "title": "Colorbleed Renamer", @@ -1361,7 +1361,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\renameShapesToTransform.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\renameShapesToTransform.py", "sourcetype": "file", "tags": ["cleanup", "renameShapesToTransform"], "title": "Rename Shapes To Transform", @@ -1369,7 +1369,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\reorderUI.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\reorderUI.py", "sourcetype": "file", "tags": ["cleanup", "reorderUI"], "title": "Reorder UI", @@ -1377,7 +1377,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\cleanup\\pastedCleaner.py", + "command": "$OPENPYPE_SCRIPTS\\cleanup\\pastedCleaner.py", "sourcetype": "file", "tags": ["cleanup", "pastedCleaner"], "title": "Pasted Cleaner", @@ -1396,7 +1396,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\yeti\\cache_selected_yeti_nodes.py", + "command": "$OPENPYPE_SCRIPTS\\others\\yeti\\cache_selected_yeti_nodes.py", "sourcetype": "file", "tags": ["others", "yeti", "cache", "selected"], "title": "Cache Selected Yeti Nodes", @@ -1411,7 +1411,7 @@ "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\hair\\recolorHairCurrentCurve", + "command": "$OPENPYPE_SCRIPTS\\others\\hair\\recolorHairCurrentCurve", "sourcetype": "file", "tags": ["others", "selectSoftSelection"], "title": "Select Soft Selection", @@ -1421,14 +1421,14 @@ }, { "type": "menu", - "command": "$PYPE_SCRIPTS\\others\\display", + "command": "$OPENPYPE_SCRIPTS\\others\\display", "sourcetype": "file", "tags": ["others", "display"], "title": "Display", "items": [ { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\display\\wireframeSelectedObjects.py", + "command": "$OPENPYPE_SCRIPTS\\others\\display\\wireframeSelectedObjects.py", "sourcetype": "file", "tags": ["others", "wireframe", "selected", "objects"], "title": "Wireframe Selected Objects", @@ -1438,7 +1438,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\archiveSceneUI.py", + "command": "$OPENPYPE_SCRIPTS\\others\\archiveSceneUI.py", "sourcetype": "file", "tags": ["others", "archiveSceneUI"], "title": "Archive Scene UI", @@ -1446,7 +1446,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\getSimilarMeshes.py", + "command": "$OPENPYPE_SCRIPTS\\others\\getSimilarMeshes.py", "sourcetype": "file", "tags": ["others", "getSimilarMeshes"], "title": "Get Similar Meshes", @@ -1454,7 +1454,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\createBoundingBoxEachSelected.py", + "command": "$OPENPYPE_SCRIPTS\\others\\createBoundingBoxEachSelected.py", "sourcetype": "file", "tags": ["others", "createBoundingBoxEachSelected"], "title": "Create BoundingBox Each Selected", @@ -1462,7 +1462,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\curveFromPositionEveryFrame.py", + "command": "$OPENPYPE_SCRIPTS\\others\\curveFromPositionEveryFrame.py", "sourcetype": "file", "tags": ["others", "curveFromPositionEveryFrame"], "title": "Curve From Position", @@ -1470,7 +1470,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\instanceLeafSmartTransform.py", + "command": "$OPENPYPE_SCRIPTS\\others\\instanceLeafSmartTransform.py", "sourcetype": "file", "tags": ["others", "instance", "leaf", "smart", "transform"], "title": "Instance Leaf Smart Transform", @@ -1478,7 +1478,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\instanceSmartTransform.py", + "command": "$OPENPYPE_SCRIPTS\\others\\instanceSmartTransform.py", "sourcetype": "file", "tags": ["others", "instance", "smart", "transform"], "title": "Instance Smart Transform", @@ -1486,7 +1486,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\randomizeUVShellsSelectedObjects.py", + "command": "$OPENPYPE_SCRIPTS\\others\\randomizeUVShellsSelectedObjects.py", "sourcetype": "file", "tags": ["others", "randomizeUVShellsSelectedObjects"], "title": "Randomize UV Shells", @@ -1494,7 +1494,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\centerPivotGroup.py", + "command": "$OPENPYPE_SCRIPTS\\others\\centerPivotGroup.py", "sourcetype": "file", "tags": ["others", "centerPivotGroup"], "title": "Center Pivot Group", @@ -1505,7 +1505,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\locatorsOnSelectedFaces.py", + "command": "$OPENPYPE_SCRIPTS\\others\\locatorsOnSelectedFaces.py", "sourcetype": "file", "tags": ["others", "locatorsOnSelectedFaces"], "title": "Locators On Selected Faces", @@ -1513,7 +1513,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\locatorsOnEdgeSelectionPrompt.py", + "command": "$OPENPYPE_SCRIPTS\\others\\locatorsOnEdgeSelectionPrompt.py", "sourcetype": "file", "tags": ["others", "locatorsOnEdgeSelectionPrompt"], "title": "Locators On Edge Selection Prompt", @@ -1524,7 +1524,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\copyDeformers.py", + "command": "$OPENPYPE_SCRIPTS\\others\\copyDeformers.py", "sourcetype": "file", "tags": ["others", "copyDeformers"], "title": "Copy Deformers", @@ -1532,7 +1532,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\selectInReferenceEditor.py", + "command": "$OPENPYPE_SCRIPTS\\others\\selectInReferenceEditor.py", "sourcetype": "file", "tags": ["others", "selectInReferenceEditor"], "title": "Select In Reference Editor", @@ -1540,7 +1540,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\selectConstrainingObject.py", + "command": "$OPENPYPE_SCRIPTS\\others\\selectConstrainingObject.py", "sourcetype": "file", "tags": ["others", "selectConstrainingObject"], "title": "Select Constraining Object", @@ -1548,7 +1548,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\deformerSetRelationsUI.py", + "command": "$OPENPYPE_SCRIPTS\\others\\deformerSetRelationsUI.py", "sourcetype": "file", "tags": ["others", "deformerSetRelationsUI"], "title": "Deformer Set Relations UI", @@ -1556,7 +1556,7 @@ }, { "type": "action", - "command": "$PYPE_SCRIPTS\\others\\recreateBaseNodesForAllLatticeNodes.py", + "command": "$OPENPYPE_SCRIPTS\\others\\recreateBaseNodesForAllLatticeNodes.py", "sourcetype": "file", "tags": ["others", "recreate", "base", "nodes", "lattice"], "title": "Recreate Base Nodes For Lattice Nodes", diff --git a/pype/hosts/maya/plugins/create/create_render.py b/pype/hosts/maya/plugins/create/create_render.py index 1d06cf7080..60ef670f58 100644 --- a/pype/hosts/maya/plugins/create/create_render.py +++ b/pype/hosts/maya/plugins/create/create_render.py @@ -274,7 +274,7 @@ class CreateRender(plugin.Creator): # authentication token expired so we need to login to Muster # again to get it. We use Pype API call to show login window. api_url = "{}/muster/show_login".format( - os.environ["PYPE_WEBSERVER_URL"]) + os.environ["OPENPYPE_WEBSERVER_URL"]) self.log.debug(api_url) login_response = self._requests_get(api_url, timeout=1) if login_response.status_code != 200: @@ -296,7 +296,7 @@ class CreateRender(plugin.Creator): """ if "verify" not in kwargs: kwargs["verify"] = ( - False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True + False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True ) # noqa return requests.post(*args, **kwargs) @@ -315,6 +315,6 @@ class CreateRender(plugin.Creator): """ if "verify" not in kwargs: kwargs["verify"] = ( - False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True + False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True ) # noqa return requests.get(*args, **kwargs) diff --git a/pype/hosts/maya/plugins/create/create_vrayscene.py b/pype/hosts/maya/plugins/create/create_vrayscene.py index f37a6c4e20..7724edbe63 100644 --- a/pype/hosts/maya/plugins/create/create_vrayscene.py +++ b/pype/hosts/maya/plugins/create/create_vrayscene.py @@ -191,7 +191,7 @@ class CreateVRayScene(plugin.Creator): # authentication token expired so we need to login to Muster # again to get it. We use Pype API call to show login window. api_url = "{}/muster/show_login".format( - os.environ["PYPE_WEBSERVER_URL"]) + os.environ["OPENPYPE_WEBSERVER_URL"]) self.log.debug(api_url) login_response = self._requests_get(api_url, timeout=1) if login_response.status_code != 200: @@ -213,7 +213,7 @@ class CreateVRayScene(plugin.Creator): """ if "verify" not in kwargs: kwargs["verify"] = ( - False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True + False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True ) # noqa return requests.post(*args, **kwargs) @@ -232,6 +232,6 @@ class CreateVRayScene(plugin.Creator): """ if "verify" not in kwargs: kwargs["verify"] = ( - False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True + False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True ) # noqa return requests.get(*args, **kwargs) diff --git a/pype/hosts/maya/plugins/publish/submit_maya_muster.py b/pype/hosts/maya/plugins/publish/submit_maya_muster.py index e31f989224..14edc25b12 100644 --- a/pype/hosts/maya/plugins/publish/submit_maya_muster.py +++ b/pype/hosts/maya/plugins/publish/submit_maya_muster.py @@ -310,7 +310,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): output_dir = instance.data["outputDir"] metadata_path = os.path.join(output_dir, metadata_filename) - pype_root = os.environ["PYPE_SETUP_PATH"] + pype_root = os.environ["OPENPYPE_SETUP_PATH"] # we must provide either full path to executable or use musters own # python named MPython.exe, residing directly in muster bin @@ -509,7 +509,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): environment[path] = os.environ[path] environment["PATH"] = os.environ["PATH"] - # self.log.debug("enviro: {}".format(environment['PYPE_SCRIPTS'])) + # self.log.debug("enviro: {}".format(environment['OPENPYPE_SCRIPTS'])) clean_environment = {} for key, value in environment.items(): clean_path = "" @@ -559,5 +559,5 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.post(*args, **kwargs) diff --git a/pype/hosts/maya/plugins/publish/validate_muster_connection.py b/pype/hosts/maya/plugins/publish/validate_muster_connection.py index 868135677e..9077314831 100644 --- a/pype/hosts/maya/plugins/publish/validate_muster_connection.py +++ b/pype/hosts/maya/plugins/publish/validate_muster_connection.py @@ -85,7 +85,7 @@ class ValidateMusterConnection(pyblish.api.ContextPlugin): Renew authentication token by logging into Muster """ api_url = "{}/muster/show_login".format( - os.environ["PYPE_WEBSERVER_URL"]) + os.environ["OPENPYPE_WEBSERVER_URL"]) cls.log.debug(api_url) response = cls._requests_get(api_url, timeout=1) if response.status_code != 200: @@ -103,7 +103,7 @@ class ValidateMusterConnection(pyblish.api.ContextPlugin): of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.post(*args, **kwargs) def _requests_get(self, *args, **kwargs): @@ -117,5 +117,5 @@ class ValidateMusterConnection(pyblish.api.ContextPlugin): of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.get(*args, **kwargs) diff --git a/pype/hosts/maya/startup/userSetup.py b/pype/hosts/maya/startup/userSetup.py index a562d3ab9e..68558b7f0d 100644 --- a/pype/hosts/maya/startup/userSetup.py +++ b/pype/hosts/maya/startup/userSetup.py @@ -14,7 +14,7 @@ shelf_preset = settings['maya'].get('project_shelf') if shelf_preset: project = os.environ["AVALON_PROJECT"] - icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], + icon_path = os.path.join(os.environ['OPENPYPE_PROJECT_SCRIPTS'], project, "icons") icon_path = os.path.abspath(icon_path) diff --git a/pype/hosts/premiere/lib.py b/pype/hosts/premiere/lib.py index 410e159560..7981fd5608 100644 --- a/pype/hosts/premiere/lib.py +++ b/pype/hosts/premiere/lib.py @@ -168,7 +168,7 @@ def clearing_caches_ui(): def test_rest_api_server(env): # from pprint import pformat - rest_url = env.get("PYPE_WEBSERVER_URL") + rest_url = env.get("OPENPYPE_WEBSERVER_URL") project_name = "{AVALON_PROJECT}".format(**env) URL = "/".join((rest_url, "avalon/projects", diff --git a/pype/hosts/premiere/ppro/js/pype_restapi_client.js b/pype/hosts/premiere/ppro/js/pype_restapi_client.js index be73a2fb8c..21beb8c5de 100644 --- a/pype/hosts/premiere/ppro/js/pype_restapi_client.js +++ b/pype/hosts/premiere/ppro/js/pype_restapi_client.js @@ -14,7 +14,7 @@ class PypeRestApiClient { * @return {url string} */ _getApiServerUrl() { - var url = this.env.PYPE_WEBSERVER_URL; + var url = this.env.OPENPYPE_WEBSERVER_URL; return url } diff --git a/pype/hosts/unreal/api/lib.py b/pype/hosts/unreal/api/lib.py index 02b1ae5bf5..0b0c5b608d 100644 --- a/pype/hosts/unreal/api/lib.py +++ b/pype/hosts/unreal/api/lib.py @@ -146,7 +146,7 @@ def create_unreal_project(project_name: str, directory is not found in plugin folders as this indicates this is only source distribution of the plugin. Dev mode is also set by preset file `unreal/project_setup.json` in - **PYPE_CONFIG**. + **OPENPYPE_CONFIG**. :type dev_mode: bool :returns: None """ @@ -180,17 +180,17 @@ def create_unreal_project(project_name: str, } if preset["install_unreal_python_engine"]: - # If `PYPE_UNREAL_ENGINE_PYTHON_PLUGIN` is set, copy it from there to - # support offline installation. + # If `OPENPYPE_UNREAL_ENGINE_PYTHON_PLUGIN` is set, copy it from there + # to support offline installation. # Otherwise clone UnrealEnginePython to Plugins directory # https://github.com/20tab/UnrealEnginePython.git uep_path = os.path.join(plugins_path, "UnrealEnginePython") - if os.environ.get("PYPE_UNREAL_ENGINE_PYTHON_PLUGIN"): + if os.environ.get("OPENPYPE_UNREAL_ENGINE_PYTHON_PLUGIN"): os.makedirs(uep_path, exist_ok=True) dir_util._path_created = {} dir_util.copy_tree( - os.environ.get("PYPE_UNREAL_ENGINE_PYTHON_PLUGIN"), + os.environ.get("OPENPYPE_UNREAL_ENGINE_PYTHON_PLUGIN"), uep_path) else: # WARNING: this will trigger dev_mode, because we need to compile From 025d05e1f3336f7d15cc0a4d36c403d365765568 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:45:18 +0200 Subject: [PATCH 242/295] Resolve: clean up menu and make it following ux conventions --- pype/hosts/resolve/api/menu.py | 42 +++++++++++++-------------- pype/hosts/resolve/api/menu_style.qss | 2 ++ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/pype/hosts/resolve/api/menu.py b/pype/hosts/resolve/api/menu.py index 68ba3af967..5ed7aeab34 100644 --- a/pype/hosts/resolve/api/menu.py +++ b/pype/hosts/resolve/api/menu.py @@ -59,19 +59,19 @@ class OpenPypeMenu(QtWidgets.QWidget): ) self.setWindowTitle("OpenPype") - workfiles_btn = QtWidgets.QPushButton("Workfiles", self) - create_btn = QtWidgets.QPushButton("Create", self) - publish_btn = QtWidgets.QPushButton("Publish", self) - load_btn = QtWidgets.QPushButton("Load", self) - inventory_btn = QtWidgets.QPushButton("Inventory", self) - libload_btn = QtWidgets.QPushButton("Library", self) - rename_btn = QtWidgets.QPushButton("Rename", self) - set_colorspace_btn = QtWidgets.QPushButton( - "Set colorspace from presets", self - ) - reset_resolution_btn = QtWidgets.QPushButton( - "Reset Resolution from peresets", self - ) + workfiles_btn = QtWidgets.QPushButton("Workfiles ...", self) + create_btn = QtWidgets.QPushButton("Create ...", self) + publish_btn = QtWidgets.QPushButton("Publish ...", self) + load_btn = QtWidgets.QPushButton("Load ...", self) + inventory_btn = QtWidgets.QPushButton("Inventory ...", self) + libload_btn = QtWidgets.QPushButton("Library ...", self) + # rename_btn = QtWidgets.QPushButton("Rename ...", self) + # set_colorspace_btn = QtWidgets.QPushButton( + # "Set colorspace from presets", self + # ) + # reset_resolution_btn = QtWidgets.QPushButton( + # "Reset Resolution from peresets", self + # ) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(10, 20, 10, 20) @@ -86,14 +86,14 @@ class OpenPypeMenu(QtWidgets.QWidget): layout.addWidget(libload_btn) - layout.addWidget(Spacer(15, self)) + # layout.addWidget(Spacer(15, self)) - layout.addWidget(rename_btn) + # layout.addWidget(rename_btn) - layout.addWidget(Spacer(15, self)) + # layout.addWidget(Spacer(15, self)) - layout.addWidget(set_colorspace_btn) - layout.addWidget(reset_resolution_btn) + # layout.addWidget(set_colorspace_btn) + # layout.addWidget(reset_resolution_btn) self.setLayout(layout) @@ -103,9 +103,9 @@ class OpenPypeMenu(QtWidgets.QWidget): load_btn.clicked.connect(self.on_load_clicked) inventory_btn.clicked.connect(self.on_inventory_clicked) libload_btn.clicked.connect(self.on_libload_clicked) - rename_btn.clicked.connect(self.on_rename_clicked) - set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked) - reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked) + # rename_btn.clicked.connect(self.on_rename_clicked) + # set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked) + # reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked) def on_workfile_clicked(self): print("Clicked Workfile") diff --git a/pype/hosts/resolve/api/menu_style.qss b/pype/hosts/resolve/api/menu_style.qss index fd947e58c1..d2d3d1ed37 100644 --- a/pype/hosts/resolve/api/menu_style.qss +++ b/pype/hosts/resolve/api/menu_style.qss @@ -52,6 +52,8 @@ QLineEdit { } #OpenPypeMenu { + qproperty-alignment: AlignLeft; + min-width: 10em; border: 1px solid #fef9ef; } From 43572b5b6f32c0013f5eb4a45f27e13d6a648782 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 15:46:08 +0200 Subject: [PATCH 243/295] changed pype env prefix in modules --- pype/modules/avalon_apps/avalon_app.py | 2 +- .../publish/submit_aftereffects_deadline.py | 8 +++--- .../publish/submit_harmony_deadline..py | 8 +++--- .../plugins/publish/submit_maya_deadline.py | 28 +++++++++---------- .../plugins/publish/submit_nuke_deadline.py | 4 +-- .../plugins/publish/submit_publish_job.py | 22 +++++++-------- .../publish/validate_deadline_connection.py | 2 +- .../action_applications.py | 2 +- .../ftrack/ftrack_server/socket_thread.py | 4 +-- .../ftrack/lib/ftrack_action_handler.py | 2 +- .../validate_custom_ftrack_attributes.py | 2 +- pype/modules/muster/muster.py | 2 +- pype/modules/timers_manager/timers_manager.py | 2 +- pype/modules/user/user_module.py | 2 +- pype/modules/webserver/webserver_module.py | 4 +-- 15 files changed, 47 insertions(+), 47 deletions(-) diff --git a/pype/modules/avalon_apps/avalon_app.py b/pype/modules/avalon_apps/avalon_app.py index 38d6e4394c..60f62fe731 100644 --- a/pype/modules/avalon_apps/avalon_app.py +++ b/pype/modules/avalon_apps/avalon_app.py @@ -23,7 +23,7 @@ class AvalonModule(PypeModule, ITrayModule, IWebServerRoutes): avalon_mongo_url = avalon_settings["AVALON_MONGO"] # Use pype mongo if Avalon's mongo not defined if not avalon_mongo_url: - avalon_mongo_url = os.environ["PYPE_MONGO"] + avalon_mongo_url = os.environ["OPENPYPE_MONGO"] thumbnail_root = os.environ.get("AVALON_THUMBNAIL_ROOT") if not thumbnail_root: diff --git a/pype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/pype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py index c1a6de4ce3..5ec5129fa4 100644 --- a/pype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/pype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -64,9 +64,9 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline "AVALON_ASSET", "AVALON_TASK", "AVALON_APP_NAME", - "PYPE_USERNAME", - "PYPE_DEV", - "PYPE_LOG_NO_COLORS" + "OPENPYPE_USERNAME", + "OPENPYPE_DEV", + "OPENPYPE_LOG_NO_COLORS" ] environment = dict({key: os.environ[key] for key in keys @@ -78,7 +78,7 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline key=key, value=val) # to recognize job from PYPE for turning Event On/Off - dln_job_info.EnvironmentKeyValue = "PYPE_RENDER_JOB=1" + dln_job_info.EnvironmentKeyValue = "OPENPYPE_RENDER_JOB=1" return dln_job_info diff --git a/pype/modules/deadline/plugins/publish/submit_harmony_deadline..py b/pype/modules/deadline/plugins/publish/submit_harmony_deadline..py index 8e85937353..d723490a69 100644 --- a/pype/modules/deadline/plugins/publish/submit_harmony_deadline..py +++ b/pype/modules/deadline/plugins/publish/submit_harmony_deadline..py @@ -273,9 +273,9 @@ class HarmonySubmitDeadline( "AVALON_ASSET", "AVALON_TASK", "AVALON_APP_NAME", - "PYPE_USERNAME", - "PYPE_DEV", - "PYPE_LOG_NO_COLORS" + "OPENPYPE_USERNAME", + "OPENPYPE_DEV", + "OPENPYPE_LOG_NO_COLORS" ] environment = dict({key: os.environ[key] for key in keys @@ -288,7 +288,7 @@ class HarmonySubmitDeadline( value=val) # to recognize job from PYPE for turning Event On/Off - job_info.EnvironmentKeyValue = "PYPE_RENDER_JOB=1" + job_info.EnvironmentKeyValue = "OPENPYPE_RENDER_JOB=1" return job_info diff --git a/pype/modules/deadline/plugins/publish/submit_maya_deadline.py b/pype/modules/deadline/plugins/publish/submit_maya_deadline.py index b17dd6ba8d..041a351de9 100644 --- a/pype/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/pype/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -441,17 +441,17 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): "AVALON_ASSET", "AVALON_TASK", "AVALON_APP_NAME", - "PYPE_USERNAME", - "PYPE_DEV", - "PYPE_LOG_NO_COLORS" + "OPENPYPE_USERNAME", + "OPENPYPE_DEV", + "OPENPYPE_LOG_NO_COLORS" ] environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **api.Session) - environment["PYPE_LOG_NO_COLORS"] = "1" - environment["PYPE_MAYA_VERSION"] = cmds.about(v=True) + environment["OPENPYPE_LOG_NO_COLORS"] = "1" + environment["OPENPYPE_MAYA_VERSION"] = cmds.about(v=True) # to recognize job from PYPE for turning Event On/Off - environment["PYPE_RENDER_JOB"] = "1" + environment["OPENPYPE_RENDER_JOB"] = "1" self.payload_skeleton["JobInfo"].update({ "EnvironmentKeyValue%d" % index: "{key}={value}".format( key=key, @@ -858,20 +858,20 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): envs.append( "AVALON_APP_NAME={}".format(os.environ.get("AVALON_APP_NAME"))) envs.append( - "PYPE_ASS_EXPORT_RENDER_LAYER={}".format(data["renderlayer"])) + "OPENPYPE_ASS_EXPORT_RENDER_LAYER={}".format(data["renderlayer"])) envs.append( - "PYPE_ASS_EXPORT_SCENE_FILE={}".format(data["filepath"])) + "OPENPYPE_ASS_EXPORT_SCENE_FILE={}".format(data["filepath"])) envs.append( - "PYPE_ASS_EXPORT_OUTPUT={}".format( + "OPENPYPE_ASS_EXPORT_OUTPUT={}".format( payload['JobInfo']['OutputFilename0'])) envs.append( - "PYPE_ASS_EXPORT_START={}".format( + "OPENPYPE_ASS_EXPORT_START={}".format( int(self._instance.data["frameStartHandle"]))) envs.append( - "PYPE_ASS_EXPORT_END={}".format( + "OPENPYPE_ASS_EXPORT_END={}".format( int(self._instance.data["frameEndHandle"]))) envs.append( - "PYPE_ASS_EXPORT_STEP={}".format(1)) + "OPENPYPE_ASS_EXPORT_STEP={}".format(1)) i = 0 for e in envs: @@ -984,7 +984,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa # add 10sec timeout before bailing out kwargs['timeout'] = 10 return requests.post(*args, **kwargs) @@ -1003,7 +1003,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa # add 10sec timeout before bailing out kwargs['timeout'] = 10 return requests.get(*args, **kwargs) diff --git a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py index a4653427bb..2e30e624ef 100644 --- a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -237,7 +237,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): "PYBLISHPLUGINPATH", "NUKE_PATH", "TOOL_ENV", - "PYPE_DEV", + "OPENPYPE_DEV", "FOUNDRY_LICENSE" ] environment = dict({key: os.environ[key] for key in keys @@ -279,7 +279,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): environment = clean_environment # to recognize job from PYPE for turning Event On/Off - environment["PYPE_RENDER_JOB"] = "1" + environment["OPENPYPE_RENDER_JOB"] = "1" payload["JobInfo"].update({ "EnvironmentKeyValue%d" % index: "{key}={value}".format( key=key, diff --git a/pype/modules/deadline/plugins/publish/submit_publish_job.py b/pype/modules/deadline/plugins/publish/submit_publish_job.py index 38d328b1cb..8f937b23df 100644 --- a/pype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/pype/modules/deadline/plugins/publish/submit_publish_job.py @@ -114,16 +114,16 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "PYPE_METADATA_FILE", + "OPENPYPE_METADATA_FILE", "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", "AVALON_APP_NAME", - "PYPE_PUBLISH_JOB" - "PYPE_LOG_NO_COLORS", - "PYPE_USERNAME", - "PYPE_RENDER_JOB", - "PYPE_PUBLISH_JOB" + "OPENPYPE_PUBLISH_JOB" + "OPENPYPE_LOG_NO_COLORS", + "OPENPYPE_USERNAME", + "OPENPYPE_RENDER_JOB", + "OPENPYPE_PUBLISH_JOB" ] # custom deadline atributes @@ -223,10 +223,10 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): environment["AVALON_ASSET"] = io.Session["AVALON_ASSET"] environment["AVALON_TASK"] = io.Session["AVALON_TASK"] environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME") - environment["PYPE_LOG_NO_COLORS"] = "1" - environment["PYPE_USERNAME"] = instance.context.data["user"] - environment["PYPE_PUBLISH_JOB"] = "1" - environment["PYPE_RENDER_JOB"] = "0" + environment["OPENPYPE_LOG_NO_COLORS"] = "1" + environment["OPENPYPE_USERNAME"] = instance.context.data["user"] + environment["OPENPYPE_PUBLISH_JOB"] = "1" + environment["OPENPYPE_RENDER_JOB"] = "0" args = [ 'publish', @@ -1048,4 +1048,4 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # Directory publish_folder = os.path.dirname(file_path) - return publish_folder \ No newline at end of file + return publish_folder diff --git a/pype/modules/deadline/plugins/publish/validate_deadline_connection.py b/pype/modules/deadline/plugins/publish/validate_deadline_connection.py index 1c49e68ee1..88b3f42d49 100644 --- a/pype/modules/deadline/plugins/publish/validate_deadline_connection.py +++ b/pype/modules/deadline/plugins/publish/validate_deadline_connection.py @@ -44,5 +44,5 @@ class ValidateDeadlineConnection(pyblish.api.ContextPlugin): of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.get(*args, **kwargs) diff --git a/pype/modules/ftrack/event_handlers_user/action_applications.py b/pype/modules/ftrack/event_handlers_user/action_applications.py index 2c42cadfb7..fcfebe5078 100644 --- a/pype/modules/ftrack/event_handlers_user/action_applications.py +++ b/pype/modules/ftrack/event_handlers_user/action_applications.py @@ -26,7 +26,7 @@ class AppplicationsAction(BaseAction): type = "Application" label = "Application action" identifier = "pype_app.{}.".format(str(uuid4())) - icon_url = os.environ.get("PYPE_STATICS_SERVER") + icon_url = os.environ.get("OPENPYPE_STATICS_SERVER") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/pype/modules/ftrack/ftrack_server/socket_thread.py b/pype/modules/ftrack/ftrack_server/socket_thread.py index a895e0b900..181fad5ce5 100644 --- a/pype/modules/ftrack/ftrack_server/socket_thread.py +++ b/pype/modules/ftrack/ftrack_server/socket_thread.py @@ -12,7 +12,7 @@ from pype.lib import get_pype_execute_args class SocketThread(threading.Thread): """Thread that checks suprocess of storer of processor of events""" - MAX_TIMEOUT = int(os.environ.get("PYPE_FTRACK_SOCKET_TIMEOUT", 45)) + MAX_TIMEOUT = int(os.environ.get("OPENPYPE_FTRACK_SOCKET_TIMEOUT", 45)) def __init__(self, name, port, filepath, additional_args=[]): super(SocketThread, self).__init__() @@ -57,7 +57,7 @@ class SocketThread(threading.Thread): ) env = os.environ.copy() - env["PYPE_PROCESS_MONGO_ID"] = str(Logger.mongo_process_id) + env["OPENPYPE_PROCESS_MONGO_ID"] = str(Logger.mongo_process_id) # Pype executable (with path to start script if not build) args = get_pype_execute_args( # Add `run` command diff --git a/pype/modules/ftrack/lib/ftrack_action_handler.py b/pype/modules/ftrack/lib/ftrack_action_handler.py index d95c81955e..2bff9d8cb3 100644 --- a/pype/modules/ftrack/lib/ftrack_action_handler.py +++ b/pype/modules/ftrack/lib/ftrack_action_handler.py @@ -3,7 +3,7 @@ from .ftrack_base_handler import BaseHandler def statics_icon(*icon_statics_file_parts): - statics_server = os.environ.get("PYPE_STATICS_SERVER") + statics_server = os.environ.get("OPENPYPE_STATICS_SERVER") if not statics_server: return None return "/".join((statics_server, *icon_statics_file_parts)) diff --git a/pype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py b/pype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py index 03aa8844fd..549f48889d 100644 --- a/pype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py +++ b/pype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py @@ -8,7 +8,7 @@ class ValidateFtrackAttributes(pyblish.api.InstancePlugin): Attributes to be validated are specified in: - `$PYPE_CONFIG/presets/<host>/ftrack_attributes.json` + `$OPENPYPE_CONFIG/presets/<host>/ftrack_attributes.json` This is array (list) of checks in format: [ diff --git a/pype/modules/muster/muster.py b/pype/modules/muster/muster.py index 5595ccff15..1a82926802 100644 --- a/pype/modules/muster/muster.py +++ b/pype/modules/muster/muster.py @@ -153,5 +153,5 @@ class MusterModule(PypeModule, ITrayModule, IWebServerRoutes): of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: - kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa + kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.post(*args, **kwargs) diff --git a/pype/modules/timers_manager/timers_manager.py b/pype/modules/timers_manager/timers_manager.py index b83f51f0ba..a8ea5799e6 100644 --- a/pype/modules/timers_manager/timers_manager.py +++ b/pype/modules/timers_manager/timers_manager.py @@ -221,7 +221,7 @@ class TimersManager(PypeModule, ITrayService, IIdleManager, IWebServerRoutes): def change_timer_from_host(self, project_name, asset_name, task_name): """Prepared method for calling change timers on REST api""" - webserver_url = os.environ.get("PYPE_WEBSERVER_URL") + webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") if not webserver_url: self.log.warning("Couldn't find webserver url") return diff --git a/pype/modules/user/user_module.py b/pype/modules/user/user_module.py index 71c5fd124e..7d257f1781 100644 --- a/pype/modules/user/user_module.py +++ b/pype/modules/user/user_module.py @@ -29,7 +29,7 @@ class UserModule(PypeModule, ITrayModule, IWebServerRoutes): appdirs.user_data_dir('pype-app', 'pype') ) cred_filename = 'user_info.json' - env_name = "PYPE_USERNAME" + env_name = "OPENPYPE_USERNAME" name = "user" diff --git a/pype/modules/webserver/webserver_module.py b/pype/modules/webserver/webserver_module.py index 3b3f0e7a79..b3fb83596d 100644 --- a/pype/modules/webserver/webserver_module.py +++ b/pype/modules/webserver/webserver_module.py @@ -49,8 +49,8 @@ class WebServerModule(PypeModule, ITrayService): self.server_manager.add_static(static_prefix, resources.RESOURCES_DIR) webserver_url = "http://localhost:{}".format(self.port) - os.environ["PYPE_WEBSERVER_URL"] = webserver_url - os.environ["PYPE_STATICS_SERVER"] = "{}{}".format( + os.environ["OPENPYPE_WEBSERVER_URL"] = webserver_url + os.environ["OPENPYPE_STATICS_SERVER"] = "{}{}".format( webserver_url, static_prefix ) From adecc8b248dfcbaa35aa38dd6e45cf5f86638bfa Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:47:43 +0200 Subject: [PATCH 244/295] Merge conflict --- igniter/pype.ico | Bin 109515 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 igniter/pype.ico diff --git a/igniter/pype.ico b/igniter/pype.ico deleted file mode 100644 index 746fc36ba29274127740c24feb3fb834424bfdbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109515 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 P00000NkvXXu0mjf8ME^t From c107efeab6047cfc3d327bf6bf8c761870ab98c9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek <jakub@orbi.tools> Date: Thu, 1 Apr 2021 15:48:27 +0200 Subject: [PATCH 245/295] merge conflict --- igniter/pype_icon.png | Bin 1723 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 igniter/pype_icon.png diff --git a/igniter/pype_icon.png b/igniter/pype_icon.png deleted file mode 100644 index c17d6ee4c1806c78a34d0d15e7a7d47f5be47d59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1723 zcmbVNZD<>19KS5uWbN9eR-BVguQwPidar3N$+4{IlCF(4ZD<2+$IxBwo+L+eFTJ}q zY1}jsRy&8d2^Kf^At3mI!w++lfy@=GFsv0O>K8xRZB##~6N?l?>vL%mI-L%8@Z9s< z^ZcIQ|NVc*V*|a7^^epe2+|no3lG5=wT80}zKwi-6;4~VzA*zq8d|JjL(ZIi7(woT zNQ#e|qtT~0L6r$!R1<*6$r?l>$lk7;#tY-XL=zw-DFN)~kFH>-BnGe%Pn3#kA&{2( z@;VsK55$H1xZoGDu6^j<90v(xVDe~A&L{?#3t(kl4z8_j5<|-nb3A}`TLRJ1XbcUh zIzU;1!Uc+AP_Lh$+0IUudIDuAh9W5sNi#Uja#SZrd(p~+L20^}<c7irDze~L085*u z#*t(;n<cVtLe*0w?f3ghiXj;WhX~x5R!lyJE5`0BLl_u>E@`HuDyYTCC)7zZfI&?+ zOpvu2tzuN%1RX}^c#Wh9$}*`86ond2o76L9;i5o-43L3h8W2m@uv%I*RU@tb3w7=I zHUZGJ(P&M^9d(iAnh3+}nSy3i9CAmr5ueroIRp%KQWrqa6jXD!WsSy#bikXc9#_>& zHBhmt$|yq<4B9>-DWaM+IyPMZVcrA*%!(RL`Ei<#!>GC4oZI&}#c&k00gbAnl$`!2 z)XPzR&cogYg()NQCVyA3C~!$tmw9NgB=adiYDx-2Yi{I1YDU$eV5psY^L`{0is@=n z%D@9-sCPda=?Ss4pJj1|pv&q;qg+HWOkNQ{Bpkq?a|lTixdh|&B|*}Q1J;|s1#hPZ z_jkhdVg%O1dss1<^m(fH!>TZ8r9kz*_&@It>JltLK6B4JR$*GX!}Uo9jOuiybcVr1 zWtEZ8a=LK5V3k1t6Rh|H5vy!V_w0cU+H4v?(*MYd4Va-O%`C5j?iBRaUGt8F%9B>X zZrDNo-Nf?QrsA%`VaKqRwN?c`YRwKPu*2!FmHjq8@g9QM`Xk})_~=$)ZGFA#lVD<| zdj&bM_-nM_do6s{x$tM~^10yWg@%^v1s#2^ZecJo|4MNUbE)>_{5zqmQ^Chv>u+z_ zXJ44R;VT_`vZ?Uhx#AS!T-kQP9vnSV+C`;GyKe2A{rcUT1xGOBTvFPCM~Z#DH-;8% zBiGLFXmCA`?SH20Vyo8D-)0<l9{m6U7t?bmw*0akTaA|H?7>e}#O1J0bhxgxF^%y? zkwEyBqB;LXk#KCQ`_ksIkL`#zhUK;UW>dwNo<4Zd5yao3+M689&h~E|vr8TFtEYxt z%`Z!1556f3pg+|uFU8!azyAR_d2{=<)kC(#&b+@=|Ki7w=KY7+rlb9{6G2CF)1|?A z+aBNQbo2EBfwkUxeKzd;><oGGt7lu@aQ;y`cGYan?QwZsr+++O%sp`7_XCI6)``mk Z^5La}-^|RMTC{#Ik)DC@`}+^S@E26NH9r6V From b9c10f1f82524cd58a447bdda3956ef9cfc8d701 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 15:50:37 +0200 Subject: [PATCH 246/295] change Menu label to variable --- pype/hosts/maya/api/menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/maya/api/menu.py b/pype/hosts/maya/api/menu.py index cb04399a35..60ae951708 100644 --- a/pype/hosts/maya/api/menu.py +++ b/pype/hosts/maya/api/menu.py @@ -8,7 +8,7 @@ from pype.api import BuildWorkfile import maya.cmds as cmds self = sys.modules[__name__] -self._menu = "OpenPype" +self._menu = os.environ.get("AVALON_LABEL") log = logging.getLogger(__name__) From 7f15ef8d8136cf67de52ec5b3127bcd08955e8f6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT <jakub.trllo@gmail.com> Date: Thu, 1 Apr 2021 15:53:13 +0200 Subject: [PATCH 247/295] changed environment prefixes in rest of pype module --- pype/cli.py | 10 +++++----- pype/hooks/pre_python2_vendor.py | 3 +-- .../publish/collect_current_pype_user.py | 2 +- .../plugins/publish/collect_rendered_files.py | 8 ++++---- pype/plugins/publish/extract_scanline_exr.py | 2 +- pype/pype_commands.py | 2 +- pype/resources/__init__.py | 4 ++-- pype/scripts/export_maya_ass_job.py | 8 ++++---- pype/scripts/export_maya_ass_sequence.mel | 12 +++++------ pype/tools/pyblish_pype/settings.py | 2 +- .../settings/local_settings/mongo_widget.py | 2 +- .../settings/settings/widgets/widgets.py | 2 +- pype/tools/tray/pype_tray.py | 4 ++-- start.py | 20 +++++++++---------- 14 files changed, 40 insertions(+), 41 deletions(-) diff --git a/pype/cli.py b/pype/cli.py index f67cf10ea1..c6da88cbc1 100644 --- a/pype/cli.py +++ b/pype/cli.py @@ -93,7 +93,7 @@ def eventserver(debug, provided credentials will be stored for later use. """ if debug: - os.environ['PYPE_DEBUG'] = "3" + os.environ['OPENPYPE_DEBUG'] = "3" PypeCommands().launch_eventservercli( ftrack_url, @@ -139,7 +139,7 @@ def publish(debug, paths): More than one path is allowed. """ if debug: - os.environ['PYPE_DEBUG'] = '3' + os.environ['OPENPYPE_DEBUG'] = '3' PypeCommands.publish(list(paths)) @@ -164,7 +164,7 @@ def texturecopy(debug, project, asset, path): Nothing is written to database. """ if debug: - os.environ['PYPE_DEBUG'] = '3' + os.environ['OPENPYPE_DEBUG'] = '3' PypeCommands().texture_copy(project, asset, path) @@ -178,7 +178,7 @@ def texturecopy(debug, project, asset, path): default=lambda: os.environ.get('AVALON_TASK', '')) @click.option("--tools", help="List of tools to add") @click.option("--user", help="Pype user name", - default=lambda: os.environ.get('PYPE_USERNAME', '')) + default=lambda: os.environ.get('OPENPYPE_USERNAME', '')) @click.option("-fs", "--ftrack-server", help="Registered application name", @@ -214,7 +214,7 @@ def launch(app, project, asset, task, os.environ["FTRACK_API_KEY"] = ftrack_key if user: - os.environ["PYPE_USERNAME"] = user + os.environ["OPENPYPE_USERNAME"] = user # test required if not project or not asset or not task: diff --git a/pype/hooks/pre_python2_vendor.py b/pype/hooks/pre_python2_vendor.py index 6f34e44132..377431b372 100644 --- a/pype/hooks/pre_python2_vendor.py +++ b/pype/hooks/pre_python2_vendor.py @@ -11,7 +11,7 @@ class PrePython2Vendor(PreLaunchHook): def execute(self): # Prepare vendor dir path self.log.info("adding global python 2 vendor") - pype_root = os.getenv("PYPE_ROOT") + pype_root = os.getenv("OPENPYPE_ROOT") python_2_vendor = os.path.join( pype_root, "pype", @@ -32,4 +32,3 @@ class PrePython2Vendor(PreLaunchHook): # Set new PYTHONPATH to launch context environments self.launch_context.env["PYTHONPATH"] = os.pathsep.join(python_paths) - \ No newline at end of file diff --git a/pype/plugins/publish/collect_current_pype_user.py b/pype/plugins/publish/collect_current_pype_user.py index a8947dd8fb..de4e950d56 100644 --- a/pype/plugins/publish/collect_current_pype_user.py +++ b/pype/plugins/publish/collect_current_pype_user.py @@ -11,7 +11,7 @@ class CollectCurrentUserPype(pyblish.api.ContextPlugin): label = "Collect Pype User" def process(self, context): - user = os.getenv("PYPE_USERNAME", "").strip() + user = os.getenv("OPENPYPE_USERNAME", "").strip() if not user: user = context.data.get("user", getpass.getuser()) diff --git a/pype/plugins/publish/collect_rendered_files.py b/pype/plugins/publish/collect_rendered_files.py index e0f3695fd5..edf9b50b92 100644 --- a/pype/plugins/publish/collect_rendered_files.py +++ b/pype/plugins/publish/collect_rendered_files.py @@ -17,7 +17,7 @@ from avalon import api class CollectRenderedFiles(pyblish.api.ContextPlugin): """ This collector will try to find json files in provided - `PYPE_PUBLISH_DATA`. Those files _MUST_ share same context. + `OPENPYPE_PUBLISH_DATA`. Those files _MUST_ share same context. """ order = pyblish.api.CollectorOrder - 0.2 @@ -113,9 +113,9 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): def process(self, context): self._context = context - assert os.environ.get("PYPE_PUBLISH_DATA"), ( - "Missing `PYPE_PUBLISH_DATA`") - paths = os.environ["PYPE_PUBLISH_DATA"].split(os.pathsep) + assert os.environ.get("OPENPYPE_PUBLISH_DATA"), ( + "Missing `OPENPYPE_PUBLISH_DATA`") + paths = os.environ["OPENPYPE_PUBLISH_DATA"].split(os.pathsep) project_name = os.environ.get("AVALON_PROJECT") if project_name is None: diff --git a/pype/plugins/publish/extract_scanline_exr.py b/pype/plugins/publish/extract_scanline_exr.py index a801baa17c..5839105f7f 100644 --- a/pype/plugins/publish/extract_scanline_exr.py +++ b/pype/plugins/publish/extract_scanline_exr.py @@ -45,7 +45,7 @@ class ExtractScanlineExr(pyblish.api.InstancePlugin): stagingdir = os.path.normpath(repre.get("stagingDir")) - oiio_tool_path = os.getenv("PYPE_OIIO_PATH", "") + oiio_tool_path = os.getenv("OPENPYPE_OIIO_PATH", "") if not os.path.exists(oiio_tool_path): self.log.error( "OIIO tool not found in {}".format(oiio_tool_path)) diff --git a/pype/pype_commands.py b/pype/pype_commands.py index ea94a35e3a..c46d71c631 100644 --- a/pype/pype_commands.py +++ b/pype/pype_commands.py @@ -79,7 +79,7 @@ class PypeCommands: pyblish.api.register_target("filesequence") pyblish.api.register_host("shell") - os.environ["PYPE_PUBLISH_DATA"] = os.pathsep.join(paths) + os.environ["OPENPYPE_PUBLISH_DATA"] = os.pathsep.join(paths) log.info("Running publish ...") diff --git a/pype/resources/__init__.py b/pype/resources/__init__.py index fdee38ab34..ef4ed73974 100644 --- a/pype/resources/__init__.py +++ b/pype/resources/__init__.py @@ -32,7 +32,7 @@ def get_liberation_font_path(bold=False, italic=False): def pype_icon_filepath(debug=None): if debug is None: - debug = bool(os.getenv("PYPE_DEV")) + debug = bool(os.getenv("OPENPYPE_DEV")) if debug: icon_file_name = "openpype_icon_staging.png" @@ -43,7 +43,7 @@ def pype_icon_filepath(debug=None): def pype_splash_filepath(debug=None): if debug is None: - debug = bool(os.getenv("PYPE_DEV")) + debug = bool(os.getenv("OPENPYPE_DEV")) if debug: splash_file_name = "openpype_splash_staging.png" diff --git a/pype/scripts/export_maya_ass_job.py b/pype/scripts/export_maya_ass_job.py index 8d90fa00e5..6e5eff6663 100644 --- a/pype/scripts/export_maya_ass_job.py +++ b/pype/scripts/export_maya_ass_job.py @@ -49,10 +49,10 @@ def __main__(): auto_pype_root = os.path.dirname(os.path.abspath(__file__)) auto_pype_root = os.path.abspath(auto_pype_root + "../../../../..") - auto_pype_root = os.environ.get('PYPE_SETUP_PATH') or auto_pype_root - if os.environ.get('PYPE_SETUP_PATH'): + auto_pype_root = os.environ.get('OPENPYPE_SETUP_PATH') or auto_pype_root + if os.environ.get('OPENPYPE_SETUP_PATH'): print("Got Pype location from environment: {}".format( - os.environ.get('PYPE_SETUP_PATH'))) + os.environ.get('OPENPYPE_SETUP_PATH'))) pype_command = "pype.ps1" if platform.system().lower() == "linux": @@ -78,7 +78,7 @@ def __main__(): print("Set pype root to: {}".format(pype_root)) print("Paths: {}".format(kwargs.paths or [os.getcwd()])) - # paths = kwargs.paths or [os.environ.get("PYPE_METADATA_FILE")] or [os.getcwd()] # noqa + # paths = kwargs.paths or [os.environ.get("OPENPYPE_METADATA_FILE")] or [os.getcwd()] # noqa mayabatch = os.environ.get("AVALON_APP_NAME").replace("maya", "mayabatch") args = [ diff --git a/pype/scripts/export_maya_ass_sequence.mel b/pype/scripts/export_maya_ass_sequence.mel index 83d1d010ac..b3b9a8543e 100644 --- a/pype/scripts/export_maya_ass_sequence.mel +++ b/pype/scripts/export_maya_ass_sequence.mel @@ -12,12 +12,12 @@ Attributes: */ -$scene_file=`getenv "PYPE_ASS_EXPORT_SCENE_FILE"`; -$step=`getenv "PYPE_ASS_EXPORT_STEP"`; -$start=`getenv "PYPE_ASS_EXPORT_START"`; -$end=`getenv "PYPE_ASS_EXPORT_END"`; -$file_path=`getenv "PYPE_ASS_EXPORT_OUTPUT"`; -$render_layer = `getenv "PYPE_ASS_EXPORT_RENDER_LAYER"`; +$scene_file=`getenv "OPENPYPE_ASS_EXPORT_SCENE_FILE"`; +$step=`getenv "OPENPYPE_ASS_EXPORT_STEP"`; +$start=`getenv "OPENPYPE_ASS_EXPORT_START"`; +$end=`getenv "OPENPYPE_ASS_EXPORT_END"`; +$file_path=`getenv "OPENPYPE_ASS_EXPORT_OUTPUT"`; +$render_layer = `getenv "OPENPYPE_ASS_EXPORT_RENDER_LAYER"`; print("*** ASS Export Plugin\n"); diff --git a/pype/tools/pyblish_pype/settings.py b/pype/tools/pyblish_pype/settings.py index 5848cdf698..11539f67a6 100644 --- a/pype/tools/pyblish_pype/settings.py +++ b/pype/tools/pyblish_pype/settings.py @@ -24,4 +24,4 @@ TerminalFilters = { } # Allow animations in GUI -Animated = env_variable_to_bool("PYPE_PYBLISH_ANIMATED", True) +Animated = env_variable_to_bool("OPENPYPE_PYBLISH_ANIMATED", True) diff --git a/pype/tools/settings/local_settings/mongo_widget.py b/pype/tools/settings/local_settings/mongo_widget.py index c6f6ab1591..35a415b081 100644 --- a/pype/tools/settings/local_settings/mongo_widget.py +++ b/pype/tools/settings/local_settings/mongo_widget.py @@ -27,7 +27,7 @@ class PypeMongoWidget(QtWidgets.QWidget): # Input mongo_url_input = QtWidgets.QLineEdit(self) mongo_url_input.setPlaceholderText("< Pype Mongo URL >") - mongo_url_input.setText(os.environ["PYPE_MONGO"]) + mongo_url_input.setText(os.environ["OPENPYPE_MONGO"]) # Confirm button mongo_url_change_btn = QtWidgets.QPushButton("Confirm Change", self) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index ccd437ece3..d00372be03 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -643,7 +643,7 @@ class ProjectListWidget(QtWidgets.QWidget): items = [self.default] - mongo_url = os.environ["PYPE_MONGO"] + mongo_url = os.environ["OPENPYPE_MONGO"] # Force uninstall of whole avalon connection if url does not match # to current environment and set it as environment diff --git a/pype/tools/tray/pype_tray.py b/pype/tools/tray/pype_tray.py index 2d37c04136..0d3f729870 100644 --- a/pype/tools/tray/pype_tray.py +++ b/pype/tools/tray/pype_tray.py @@ -77,8 +77,8 @@ class TrayManager: self.tray_widget.showMessage(*args, **kwargs) def _add_version_item(self): - subversion = os.environ.get("PYPE_SUBVERSION") - client_name = os.environ.get("PYPE_CLIENT") + subversion = os.environ.get("OPENPYPE_SUBVERSION") + client_name = os.environ.get("OPENPYPE_CLIENT") version_string = pype.version.__version__ if subversion: diff --git a/start.py b/start.py index ba46d539ca..e8fac8c86c 100644 --- a/start.py +++ b/start.py @@ -3,7 +3,7 @@ Bootstrapping process of Pype is as follows: -`PYPE_PATH` is checked for existence - either one from environment or +`OPENPYPE_PATH` is checked for existence - either one from environment or from user settings. Precedence takes the one set by environment. On this path we try to find pype in directories version string in their names. @@ -11,16 +11,16 @@ For example: `pype-v3.0.1-foo` is valid name, or even `foo_3.0.2` - as long as version can be determined from its name _AND_ file `pype/pype/version.py` can be found inside, it is considered Pype installation. -If no Pype repositories are found in `PYPE_PATH` (user data dir) +If no Pype repositories are found in `OPENPYPE_PATH` (user data dir) then **Igniter** (Pype setup tool) will launch its GUI. -It can be used to specify `PYPE_PATH` or if it is _not_ specified, current +It can be used to specify `OPENPYPE_PATH` or if it is _not_ specified, current *"live"* repositories will be used to create zip file and copy it to appdata dir in user home and extract it there. Version will be determined by version specified in Pype module. If Pype repository directories are found in default install location -(user data dir) or in `PYPE_PATH`, it will get list of those dirs there and +(user data dir) or in `OPENPYPE_PATH`, it will get list of those dirs there and use latest one or the one specified with optional `--use-version` command line argument. If the one specified doesn't exist then latest available version will be used. All repositories in that dir will be added @@ -31,7 +31,7 @@ used. All directories under `repos` will be added to `sys.path` and `PYTHONPATH`. Pype depends on connection to `MongoDB`_. You can specify MongoDB connection -string via `PYPE_MONGO` set in environment or it can be set in user +string via `OPENPYPE_MONGO` set in environment or it can be set in user settings or via **Igniter** GUI. So, bootstrapping Pype looks like this:: @@ -40,7 +40,7 @@ So, bootstrapping Pype looks like this:: +-------------------------------------------------------+ | Determine MongoDB connection: | -| Use `PYPE_MONGO`, system keyring `pypeMongo` | +| Use `OPENPYPE_MONGO`, system keyring `pypeMongo` | +--------------------------|----------------------------+ .--- Found? --. YES NO @@ -53,7 +53,7 @@ So, bootstrapping Pype looks like this:: | | +-----------------v------------------------------------+ | | Get location of Pype: | | -| 1) Test for `PYPE_PATH` environment variable | | +| 1) Test for `OPENPYPE_PATH` environment variable | | | 2) Test `pypePath` in registry setting | | | 3) Test user data directory | | | ................................................... | | @@ -67,7 +67,7 @@ So, bootstrapping Pype looks like this:: YES NO | | | | | +--------------v------------------+ | - | | Look in `PYPE_PATH`, find | | + | | Look in `OPENPYPE_PATH`, find | | | | latest version and install it | | | | to user data dir. | | | +--------------|------------------+ | @@ -191,7 +191,7 @@ def set_avalon_environments(): # Avalon mongo URL avalon_mongo_url = ( os.environ.get("AVALON_MONGO") - or os.environ["PYPE_MONGO"] + or os.environ["OPENPYPE_MONGO"] ) os.environ.update({ # Mongo url (use same as pype has) @@ -379,7 +379,7 @@ def _find_frozen_pype(use_version: str = None, import igniter return_code = igniter.open_dialog() if return_code == 2: - os.environ["PYPE_TRYOUT"] = "1" + os.environ["OPENPYPE_TRYOUT"] = "1" if return_code == 3: # run Pype after installation From 211c6f7f4affc53f1f559ce6a68b3270dce27f96 Mon Sep 17 00:00:00 2001 From: Milan Kolar <milan@pype.club> Date: Thu, 1 Apr 2021 16:09:12 +0200 Subject: [PATCH 248/295] remove premiere --- pype/hosts/premiere/README.markdown | 6 - pype/hosts/premiere/__init__.py | 70 - .../premiere/extensions/build_extension.bat | 20 - .../extensions/com.pype.rename/.debug | 8 - .../com.pype.rename/CSXS/manifest.xml | 60 - .../extensions/com.pype.rename/ReadMe.md | 40 - .../com.pype.rename/css/bootstrap.min.css | 7 - .../com.pype.rename/css/bootstrap.min.css.map | 1 - .../com.pype.rename/css/renamer.min.css | 3 - .../com.pype.rename/css/renamer.min.css.map | 9 - .../com.pype.rename/css/renamer.scss | 26 - .../extensions/com.pype.rename/index.html | 205 - .../com.pype.rename/jsx/PPRO/Premiere.jsx | 2379 ---- .../com.pype.rename/jsx/PypeRename.jsx | 359 - .../lib/CEPEngine_extensions.js | 699 -- .../com.pype.rename/lib/CSInterface.js | 1291 --- .../extensions/com.pype.rename/lib/Vulcan.js | 459 - .../com.pype.rename/lib/bootstrap.min.js | 7 - .../com.pype.rename/lib/bootstrap.min.js.map | 1 - .../com.pype.rename/lib/jquery-3.3.1.min.js | 2 - .../com.pype.rename/lib/popper.min.js | 5 - .../extensions/com.pype.rename/lib/renamer.js | 131 - .../hosts/premiere/extensions/com.pype/.debug | 8 - .../extensions/com.pype/CSXS/manifest.xml | 56 - .../extensions/com.pype/encoding/44khz.epr | 565 - .../extensions/com.pype/encoding/48khz.epr | 251 - .../extensions/com.pype/encoding/h264.epr | 4002 ------- .../com.pype/encoding/jpeg_thumb.epr | 5470 ---------- .../com.pype/encoding/prores422.epr | 4052 ------- .../com.pype/icons/iconDarkNormal.png | Bin 18659 -> 0 bytes .../com.pype/icons/iconDarkRollover.png | Bin 18663 -> 0 bytes .../com.pype/icons/iconDisabled.png | Bin 18663 -> 0 bytes .../extensions/com.pype/icons/iconNormal.png | Bin 18225 -> 0 bytes .../com.pype/icons/iconRollover.png | Bin 18664 -> 0 bytes .../extensions/com.pype/index_remote.html | 21 - .../extensions/com.pype/jsx/JavaScript.d.ts | 2708 ----- .../extensions/com.pype/jsx/PPRO/Premiere.jsx | 3203 ------ .../com.pype/jsx/PlugPlugExternalObject.d.ts | 91 - .../com.pype/jsx/PremierePro.14.0.d.ts | 2239 ---- .../extensions/com.pype/jsx/PypeRename.jsx | 363 - .../extensions/com.pype/jsx/XMPScript.d.ts | 51 - .../extensions/com.pype/jsx/batchRenamer.jsx | 105 - .../extensions/com.pype/jsx/extendscript.d.ts | 2708 ----- .../extensions/com.pype/jsx/global.d.ts | 149 - .../extensions/com.pype/jsx/jsconfig.json | 7 - .../premiere/extensions/com.pype/jsx/pype.jsx | 1076 -- .../extensions/com.pype/jsx/testingCode._jsx | 11 - .../com.pype/lib/CEPEngine_extensions.js | 699 -- .../extensions/com.pype/lib/CSInterface.js | 1291 --- .../extensions/com.pype/lib/Vulcan.js | 459 - .../premiere/extensions/com.pype/lib/app.js | 4 - .../extensions/com.pype/lib/jquery-1.9.1.js | 9597 ----------------- .../premiere/extensions/com.pype/lib/json2.js | 534 - .../premiere/extensions/com.pype/package.json | 30 - .../premiere/extensions/com.pype/pypeApp.jsx | 15 - pype/hosts/premiere/lib.py | 193 - pype/hosts/premiere/ppro/css/avalon.min.css | 28 - .../premiere/ppro/css/avalon.min.css.map | 9 - pype/hosts/premiere/ppro/css/avalon.scss | 26 - .../hosts/premiere/ppro/css/bootstrap.min.css | 7 - .../premiere/ppro/css/bootstrap.min.css.map | 1 - pype/hosts/premiere/ppro/debug.log | 48 - pype/hosts/premiere/ppro/img/blender.png | Bin 51122 -> 0 bytes pype/hosts/premiere/ppro/index.html | 158 - pype/hosts/premiere/ppro/js/.eslintrc.json | 69 - pype/hosts/premiere/ppro/js/build.js | 4862 --------- pype/hosts/premiere/ppro/js/pype.js | 345 - .../premiere/ppro/js/pype_restapi_client.js | 69 - .../premiere/ppro/js/vendor/CSInterface-8.js | 1193 -- .../premiere/ppro/js/vendor/bootstrap.min.js | 7 - .../ppro/js/vendor/bootstrap.min.js.map | 1 - .../ppro/js/vendor/jquery-3.3.1.min.js | 2 - pype/hosts/premiere/ppro/js/vendor/json2.js | 489 - .../premiere/ppro/js/vendor/popper.min.js | 5 - 74 files changed, 53065 deletions(-) delete mode 100644 pype/hosts/premiere/README.markdown delete mode 100644 pype/hosts/premiere/__init__.py delete mode 100644 pype/hosts/premiere/extensions/build_extension.bat delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/.debug delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/CSXS/manifest.xml delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/ReadMe.md delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css.map delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css.map delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/css/renamer.scss delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/index.html delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/jsx/PypeRename.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/CEPEngine_extensions.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/CSInterface.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/Vulcan.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/bootstrap.min.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/bootstrap.min.js.map delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/jquery-3.3.1.min.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/popper.min.js delete mode 100644 pype/hosts/premiere/extensions/com.pype.rename/lib/renamer.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/.debug delete mode 100644 pype/hosts/premiere/extensions/com.pype/CSXS/manifest.xml delete mode 100644 pype/hosts/premiere/extensions/com.pype/encoding/44khz.epr delete mode 100644 pype/hosts/premiere/extensions/com.pype/encoding/48khz.epr delete mode 100644 pype/hosts/premiere/extensions/com.pype/encoding/h264.epr delete mode 100644 pype/hosts/premiere/extensions/com.pype/encoding/jpeg_thumb.epr delete mode 100644 pype/hosts/premiere/extensions/com.pype/encoding/prores422.epr delete mode 100644 pype/hosts/premiere/extensions/com.pype/icons/iconDarkNormal.png delete mode 100644 pype/hosts/premiere/extensions/com.pype/icons/iconDarkRollover.png delete mode 100644 pype/hosts/premiere/extensions/com.pype/icons/iconDisabled.png delete mode 100644 pype/hosts/premiere/extensions/com.pype/icons/iconNormal.png delete mode 100644 pype/hosts/premiere/extensions/com.pype/icons/iconRollover.png delete mode 100644 pype/hosts/premiere/extensions/com.pype/index_remote.html delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/JavaScript.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/PPRO/Premiere.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/PlugPlugExternalObject.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/PremierePro.14.0.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/PypeRename.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/XMPScript.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/batchRenamer.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/extendscript.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/global.d.ts delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/jsconfig.json delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/pype.jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype/jsx/testingCode._jsx delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/CEPEngine_extensions.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/CSInterface.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/Vulcan.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/app.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/jquery-1.9.1.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/lib/json2.js delete mode 100644 pype/hosts/premiere/extensions/com.pype/package.json delete mode 100644 pype/hosts/premiere/extensions/com.pype/pypeApp.jsx delete mode 100644 pype/hosts/premiere/lib.py delete mode 100644 pype/hosts/premiere/ppro/css/avalon.min.css delete mode 100644 pype/hosts/premiere/ppro/css/avalon.min.css.map delete mode 100644 pype/hosts/premiere/ppro/css/avalon.scss delete mode 100644 pype/hosts/premiere/ppro/css/bootstrap.min.css delete mode 100644 pype/hosts/premiere/ppro/css/bootstrap.min.css.map delete mode 100644 pype/hosts/premiere/ppro/debug.log delete mode 100644 pype/hosts/premiere/ppro/img/blender.png delete mode 100644 pype/hosts/premiere/ppro/index.html delete mode 100644 pype/hosts/premiere/ppro/js/.eslintrc.json delete mode 100644 pype/hosts/premiere/ppro/js/build.js delete mode 100644 pype/hosts/premiere/ppro/js/pype.js delete mode 100644 pype/hosts/premiere/ppro/js/pype_restapi_client.js delete mode 100644 pype/hosts/premiere/ppro/js/vendor/CSInterface-8.js delete mode 100644 pype/hosts/premiere/ppro/js/vendor/bootstrap.min.js delete mode 100644 pype/hosts/premiere/ppro/js/vendor/bootstrap.min.js.map delete mode 100644 pype/hosts/premiere/ppro/js/vendor/jquery-3.3.1.min.js delete mode 100644 pype/hosts/premiere/ppro/js/vendor/json2.js delete mode 100644 pype/hosts/premiere/ppro/js/vendor/popper.min.js diff --git a/pype/hosts/premiere/README.markdown b/pype/hosts/premiere/README.markdown deleted file mode 100644 index 8d478f4c02..0000000000 --- a/pype/hosts/premiere/README.markdown +++ /dev/null @@ -1,6 +0,0 @@ -## How to -1. start aport server -1. a. deregistering path could be used [](http://localhost:4242/pipeline/deregister_plugin_path) -2. set aport into correct context by [](http://localhost:4242/pipeline/context?project=jakub_projectx&asset=shot02&task=rotopaint&app=premiera) -3. register premiera publish plugin path [](http://localhost:4242/pipeline/register_plugin_path?publish_path=C:/Users/hubert/CODE/pype-setup/repos/pype-config/pype/plugins/premiere/publish) -4. publish with test json file [](http://localhost:4242/pipeline/publish?json_data_path=C:/Users/hubert/CODE/pype-setup/repos/pype-config/pype/premiere/example_publish_reqst.json) diff --git a/pype/hosts/premiere/__init__.py b/pype/hosts/premiere/__init__.py deleted file mode 100644 index 8a9a032c54..0000000000 --- a/pype/hosts/premiere/__init__.py +++ /dev/null @@ -1,70 +0,0 @@ -from avalon import api as avalon -from pyblish import api as pyblish -from pype.api import Logger - - -from .lib import ( - setup, - reload_pipeline, - ls, - LOAD_PATH, - CREATE_PATH, - PUBLISH_PATH -) - -__all__ = [ - "setup", - "reload_pipeline", - "ls" -] - -log = Logger().get_logger(__name__) - - -def install(): - """Install Premiere-specific functionality of avalon-core. - - This is where you install menus and register families, data - and loaders into Premiere. - - It is called automatically when installing via `api.install(premiere)`. - - See the Maya equivalent for inspiration on how to implement this. - - """ - - # Disable all families except for the ones we explicitly want to see - family_states = [ - "imagesequence", - "mov" - ] - avalon.data["familiesStateDefault"] = False - avalon.data["familiesStateToggled"] = family_states - - log.info("pype.hosts.premiere installed") - - pyblish.register_host("premiere") - pyblish.register_plugin_path(PUBLISH_PATH) - log.info("Registering Premiera plug-ins..") - - avalon.register_plugin_path(avalon.Loader, LOAD_PATH) - avalon.register_plugin_path(avalon.Creator, CREATE_PATH) - - -def uninstall(): - """Uninstall all tha was installed - - This is where you undo everything that was done in `install()`. - That means, removing menus, deregistering families and data - and everything. It should be as though `install()` was never run, - because odds are calling this function means the user is interested - in re-installing shortly afterwards. If, for example, he has been - modifying the menu or registered families. - - """ - pyblish.deregister_host("premiere") - pyblish.deregister_plugin_path(PUBLISH_PATH) - log.info("Deregistering Premiera plug-ins..") - - avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) - avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) diff --git a/pype/hosts/premiere/extensions/build_extension.bat b/pype/hosts/premiere/extensions/build_extension.bat deleted file mode 100644 index 4fcee96d21..0000000000 --- a/pype/hosts/premiere/extensions/build_extension.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off -rem You need https://github.com/Adobe-CEP/CEP-Resources/raw/master/ZXPSignCMD/4.1.1/win64/ZXPSignCmd.exe - -rem You need https://partners.adobe.com/exchangeprogram/creativecloud/support/exman-com-line-tool.html - -rem !!! make sure you run windows power shell as admin - -set pwd="12PPROext581" - -echo ">>> creating certificate ..." -.\ZXPSignCmd -selfSignedCert CZ Prague OrbiTools "Signing robot" %pwd% certificate.p12 -echo ">>> building com.pype" -.\ZXPSignCmd -sign com.pype/ pype.zxp certificate.p12 %pwd% -echo ">>> building com.pype.rename" -.\ZXPSignCmd -sign com.pype.rename/ pype_rename.zxp certificate.p12 %pwd% - -echo ">>> installing com.pype" -.\ExManCmd.exe /install .\pype.zxp -echo ">>> installing com.pype.rename" -.\ExManCmd.exe /install .\pype_rename.zxp diff --git a/pype/hosts/premiere/extensions/com.pype.rename/.debug b/pype/hosts/premiere/extensions/com.pype.rename/.debug deleted file mode 100644 index de631269e6..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/.debug +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ExtensionList> - <Extension Id="com.pype.rename"> - <HostList> - <Host Name="PPRO" Port="7776"/> - </HostList> - </Extension> -</ExtensionList> diff --git a/pype/hosts/premiere/extensions/com.pype.rename/CSXS/manifest.xml b/pype/hosts/premiere/extensions/com.pype.rename/CSXS/manifest.xml deleted file mode 100644 index 8e6c1a43c4..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/CSXS/manifest.xml +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - - -. == [ part 0f PyPE CluB ] == .- -_______________.___._____________________ -\______ \__ | |\______ \_ _____/ - | ___// | | | ___/| __)_ - | | \____ | | | | \ - |____| / ______| |____| /_______ / - \/ \/ - .. __/ CliP R3N4M3R \__ .. - ---> -<ExtensionManifest Version="5.0" ExtensionBundleId="com.pype.rename" ExtensionBundleVersion="0.1.0" -ExtensionBundleName="Pype Rename dialog" -xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <ExtensionList> - <Extension Id="com.pype.rename" Version="0.1.0" /> - </ExtensionList> - <ExecutionEnvironment> - <HostList> - <Host Name="PPRO" Version="9.0" /> - </HostList> - <LocaleList> - <Locale Code="All" /> - </LocaleList> - <RequiredRuntimeList> - <RequiredRuntime Name="CSXS" Version="6.0" /> - </RequiredRuntimeList> - </ExecutionEnvironment> - - <DispatchInfoList> - <Extension Id="com.pype.rename"> - <DispatchInfo > - <Resources> - <MainPath>./index.html</MainPath> - <ScriptPath>./jsx/PypeRename.jsx</ScriptPath> - <CEFCommandLine> - <Parameter>--allow-file-access</Parameter> - <Parameter>--allow-file-access-from-files</Parameter> - <Parameter>--mixed-context</Parameter> - </CEFCommandLine> - </Resources> - <Lifecycle> - <AutoVisible>true</AutoVisible> - </Lifecycle> - <UI> - <Type>Panel</Type> - <Menu>Pype Rename</Menu> - <Geometry> - <Size> - <Height>550</Height> - <Width>400</Width> - </Size> - </Geometry> - </UI> - </DispatchInfo> - </Extension> - </DispatchInfoList> -</ExtensionManifest> diff --git a/pype/hosts/premiere/extensions/com.pype.rename/ReadMe.md b/pype/hosts/premiere/extensions/com.pype.rename/ReadMe.md deleted file mode 100644 index d98fd99738..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/ReadMe.md +++ /dev/null @@ -1,40 +0,0 @@ -# Pype timeline items renamer - -This panel is used to rename selected clips on timeline. It is not directly interconnected with **Avalon** so it can be used separately. It has several different modes: - -### Sequential Rename with Hierarchy - -This mode uses tokens as `{folder}`, `{episode}` and `{sequence}` to rename clips along with numeric padding pattern `####`. Value for this tokens is filled in input boxes. If value is left empty, token is ignored. Those values are also stored in clips properties, so even if token is not used in clip name, it will be stored in clip property (and then used to create hierarchy when publishing into **Avalon**). `####` pattern can be arbitrary long, but is mandatory. - -Example: - -``` -{folder}_{episode}_{sequence}_##### -``` -Will result in `f01_ep01_sq01_0010` if respective tokens are set to these values. If folder token value isn't set result will be `_ep01_sq01_0010`. - -Clip numbering can be adjusted by **Start #** and **Increment** fields. Setting start to **10** and increment to **10** with number padding pattern **####** will result in clip number **0010** for first clip, **0020** for second and so on. - -### Sequential Rename - -Is same as the one above, except not using tokens. - -### Simple Rename - -This will rename shot to new specified name. If `{shot}` token is used, it will reference current clip name. So if current clip name is `clip01` and we specify new name as `{shot}_foo`, result will be **clip01_foo**. - -### Find and replace - -Classic find and replace mode, using `{shot}` token as the mode above. - -### Match sequence - -Is not implemented yet. - -### Clip Rename - -Will name clip based on filename without extension. - -### Change Case - -This will change case of clip name to `UPPER` or `lower` case. diff --git a/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css b/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css deleted file mode 100644 index e6b4977799..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v4.2.1 (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:2.25rem;background-repeat:no-repeat;background-position:center right calc(2.25rem / 4);background-size:calc(2.25rem / 2) calc(2.25rem / 2);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e")}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2.25rem;background-position:top calc(2.25rem / 4) right calc(2.25rem / 4)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:3.4375rem;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") no-repeat center right 1.75rem/1.125rem 1.125rem}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:2.25rem;background-repeat:no-repeat;background-position:center right calc(2.25rem / 4);background-size:calc(2.25rem / 2) calc(2.25rem / 2);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E")}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2.25rem;background-position:top calc(2.25rem / 4) right calc(2.25rem / 4)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:3.4375rem;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") no-repeat center right 1.75rem/1.125rem 1.125rem}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-right{right:0;left:auto}}.dropdown-menu-left{right:auto;left:0}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.dropdown-item:last-child{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(2.875rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.8125rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;color:inherit;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card{overflow:hidden}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion .card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);border-radius:.25rem;box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-dialog-centered::before{display:block;height:calc(100vh - (.5rem * 2));content:""}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-dialog-centered::before{height:calc(100vh - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media screen and (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-3by4::before{padding-top:133.333333%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css.map b/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css.map deleted file mode 100644 index 5acf96bdd1..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/css/bootstrap.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/mixins/_float.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/mixins/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v4.2.1 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `<td>` alignment by inheriting from the `<body>`, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap v4.2.1 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::-webkit-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-moz-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.8125rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(2.875rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n -ms-flex-align: center;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: 2.25rem;\n background-repeat: no-repeat;\n background-position: center right calc(2.25rem / 4);\n background-size: calc(2.25rem / 2) calc(2.25rem / 2);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: 2.25rem;\n background-position: top calc(2.25rem / 4) right calc(2.25rem / 4);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: 3.4375rem;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") no-repeat center right 1.75rem/1.125rem 1.125rem;\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-select:valid ~ .valid-feedback,\n.was-validated .custom-select:valid ~ .valid-tooltip, .custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:valid ~ .valid-feedback,\n.was-validated .form-control-file:valid ~ .valid-tooltip, .form-control-file.is-valid ~ .valid-feedback,\n.form-control-file.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: 2.25rem;\n background-repeat: no-repeat;\n background-position: center right calc(2.25rem / 4);\n background-size: calc(2.25rem / 2) calc(2.25rem / 2);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\");\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: 2.25rem;\n background-position: top calc(2.25rem / 4) right calc(2.25rem / 4);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: 3.4375rem;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\") no-repeat center right 1.75rem/1.125rem 1.125rem;\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-select:invalid ~ .invalid-feedback,\n.was-validated .custom-select:invalid ~ .invalid-tooltip, .custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:invalid ~ .invalid-feedback,\n.was-validated .form-control-file:invalid ~ .invalid-tooltip, .form-control-file.is-invalid ~ .invalid-feedback,\n.form-control-file.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:first-child {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.dropdown-item:last-child {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: -ms-inline-flexbox;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: stretch;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: -ms-flexbox;\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(2.875rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.8125rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n -webkit-transform: translateX(0.75rem);\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: 2.25rem;\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: calc(1rem + 0.4rem);\n padding: 0;\n background-color: transparent;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -webkit-appearance: none;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -moz-appearance: none;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n -ms-flex-preferred-size: 100%;\n flex-basis: 100%;\n -ms-flex-positive: 1;\n flex-grow: 1;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n color: inherit;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: -ms-flexbox;\n display: flex;\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n -ms-flex-direction: column;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n }\n .card-group > .card {\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n -webkit-column-count: 3;\n -moz-column-count: 3;\n column-count: 3;\n -webkit-column-gap: 1.25rem;\n -moz-column-gap: 1.25rem;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion .card {\n overflow: hidden;\n}\n\n.accordion .card:not(:first-of-type) .card-header:first-child {\n border-radius: 0;\n}\n\n.accordion .card:not(:first-of-type):not(:last-of-type) {\n border-bottom: 0;\n border-radius: 0;\n}\n\n.accordion .card:first-of-type {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion .card:last-of-type {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion .card .card-header {\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: -ms-flexbox;\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: -ms-flexbox;\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n -webkit-animation: progress-bar-stripes 1s linear infinite;\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.media-body {\n -ms-flex: 1;\n flex: 1;\n}\n\n.list-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush .list-group-item:last-child {\n margin-bottom: -1px;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n margin-bottom: 0;\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n max-width: 350px;\n overflow: hidden;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 0.25rem;\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n -webkit-backdrop-filter: blur(10px);\n backdrop-filter: blur(10px);\n opacity: 0;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;\n -webkit-transform: translate(0, -50px);\n transform: translate(0, -50px);\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n -webkit-transform: none;\n transform: none;\n}\n\n.modal-dialog-centered {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - (0.5rem * 2));\n content: \"\";\n}\n\n.modal-content {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: end;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n border-bottom-right-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-dialog-centered::before {\n height: calc(100vh - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after,\n.bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-top .arrow::after,\n.bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after,\n.bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-right .arrow::after,\n.bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after,\n.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-bottom .arrow::after,\n.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after,\n.bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-left .arrow::after,\n.bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n -ms-touch-action: pan-y;\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n transition: -webkit-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n -webkit-transform: translateX(100%);\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n -webkit-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n -webkit-transform: none;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: 0s 0.6s opacity;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@-webkit-keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n -webkit-animation: spinner-border .75s linear infinite;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@-webkit-keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n@keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n -webkit-animation: spinner-grow .75s linear infinite;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-3by4::before {\n padding-top: 133.333333%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v4.2.1 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.8125rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(2.875rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: 2.25rem;\n background-repeat: no-repeat;\n background-position: center right calc(2.25rem / 4);\n background-size: calc(2.25rem / 2) calc(2.25rem / 2);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: 2.25rem;\n background-position: top calc(2.25rem / 4) right calc(2.25rem / 4);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: 3.4375rem;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") no-repeat center right 1.75rem/1.125rem 1.125rem;\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-select:valid ~ .valid-feedback,\n.was-validated .custom-select:valid ~ .valid-tooltip, .custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:valid ~ .valid-feedback,\n.was-validated .form-control-file:valid ~ .valid-tooltip, .form-control-file.is-valid ~ .valid-feedback,\n.form-control-file.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: 2.25rem;\n background-repeat: no-repeat;\n background-position: center right calc(2.25rem / 4);\n background-size: calc(2.25rem / 2) calc(2.25rem / 2);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\");\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: 2.25rem;\n background-position: top calc(2.25rem / 4) right calc(2.25rem / 4);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: 3.4375rem;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\") no-repeat center right 1.75rem/1.125rem 1.125rem;\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-select:invalid ~ .invalid-feedback,\n.was-validated .custom-select:invalid ~ .invalid-tooltip, .custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:invalid ~ .invalid-feedback,\n.was-validated .form-control-file:invalid ~ .invalid-tooltip, .form-control-file.is-invalid ~ .invalid-feedback,\n.form-control-file.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:first-child {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.dropdown-item:last-child {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(2.875rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.8125rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: 2.25rem;\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: calc(1rem + 0.4rem);\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n color: inherit;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: flex;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: flex;\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: flex;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion .card {\n overflow: hidden;\n}\n\n.accordion .card:not(:first-of-type) .card-header:first-child {\n border-radius: 0;\n}\n\n.accordion .card:not(:first-of-type):not(:last-of-type) {\n border-bottom: 0;\n border-radius: 0;\n}\n\n.accordion .card:first-of-type {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion .card:last-of-type {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion .card .card-header {\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush .list-group-item:last-child {\n margin-bottom: -1px;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n margin-bottom: 0;\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n appearance: none;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n max-width: 350px;\n overflow: hidden;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 0.25rem;\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(10px);\n opacity: 0;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - (0.5rem * 2));\n content: \"\";\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n border-bottom-right-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-dialog-centered::before {\n height: calc(100vh - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after,\n.bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-top .arrow::after,\n.bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after,\n.bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-right .arrow::after,\n.bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after,\n.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-bottom .arrow::after,\n.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after,\n.bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n\n.bs-popover-left .arrow::after,\n.bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: 0s 0.6s opacity;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media screen and (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-3by4::before {\n padding-top: 133.333333%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { font-size: $h1-font-size; }\nh2, .h2 { font-size: $h2-font-size; }\nh3, .h3 { font-size: $h3-font-size; }\nh4, .h4 { font-size: $h4-font-size; }\nh5, .h5 { font-size: $h5-font-size; }\nh6, .h6 { font-size: $h6-font-size; }\n\n.lead {\n font-size: $lead-font-size;\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n font-size: $display1-size;\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n font-size: $display2-size;\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n font-size: $display3-size;\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n font-size: $display4-size;\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n font-size: $small-font-size;\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled;\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n font-size: $blockquote-font-size;\n}\n\n.blockquote-footer {\n display: block;\n font-size: $blockquote-small-font-size;\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid;\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid;\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: $figure-caption-font-size;\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n// stylelint-disable indentation, media-query-list-comma-newline-after\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n}\n","// Single side border-radius\n\n@mixin border-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n","// Inline code\ncode {\n font-size: $code-font-size;\n color: $code-color;\n word-break: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n font-size: $kbd-font-size;\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n font-size: $code-font-size;\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n\n .table {\n background-color: $body-bg;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-size: $input-font-size;\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @if $enable-rounded {\n // Manually use the if/else instead of the mixin to account for iOS override\n border-radius: $input-border-radius;\n } @else {\n // Otherwise undo the iOS default\n border-radius: 0;\n }\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus();\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: calc(#{$input-padding-y} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});\n margin-bottom: 0; // Override the `<label>/<legend>` default\n font-size: inherit; // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});\n font-size: $input-font-size-lg;\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});\n font-size: $input-font-size-sm;\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: $input-padding-y;\n padding-bottom: $input-padding-y;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n font-size: $input-font-size-sm;\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n font-size: $input-font-size-lg;\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@include form-validation-state(\"valid\", $form-feedback-valid-color);\n@include form-validation-state(\"invalid\", $form-feedback-invalid-color);\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-blacklist\n@mixin transition($transition...) {\n @if $enable-transitions {\n @if length($transition) == 0 {\n transition: $transition-base;\n } @else {\n transition: $transition;\n }\n }\n\n @if $enable-prefers-reduced-motion-media-query {\n @media screen and (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus() {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $input-focus-box-shadow;\n } @else {\n box-shadow: $input-focus-box-shadow;\n }\n }\n}\n\n\n@mixin form-validation-state($state, $color) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n font-size: $form-feedback-font-size;\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n font-size: $form-feedback-tooltip-font-size;\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n }\n\n .form-control {\n .was-validated &:#{$state},\n &.is-#{$state} {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-repeat: no-repeat;\n background-position: center right calc(#{$input-height-inner} / 4);\n background-size: calc(#{$input-height-inner} / 2) calc(#{$input-height-inner} / 2);\n\n @if $state == \"valid\" {\n background-image: $form-feedback-icon-valid;\n } @else {\n background-image: $form-feedback-icon-invalid;\n }\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n .was-validated &:#{$state},\n &.is-#{$state} {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top calc(#{$input-height-inner} / 4) right calc(#{$input-height-inner} / 4);\n }\n }\n }\n\n .custom-select {\n .was-validated &:#{$state},\n &.is-#{$state} {\n border-color: $color;\n\n @if $enable-validation-icons {\n $form-feedback-icon: if($state == \"valid\", $form-feedback-icon-valid, $form-feedback-icon-invalid);\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, $form-feedback-icon no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n\n .form-control-file {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .form-check-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .btn elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n box-shadow: none;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows and $btn-active-box-shadow != none {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n font-size: $font-size;\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @if $enable-rounded {\n border-radius: $border-radius;\n } @else {\n border-radius: 0;\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n.fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n // Generate the caret automatically\n @include caret;\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y 0;\n margin: $dropdown-spacer 0 0; // override default ul\n font-size: $font-size-base; // Redeclare because nesting can cause inheritance issues\n color: $body-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When enabled Popper.js, reset basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n\n @include hover-focus {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-padding-y $dropdown-item-padding-x;\n margin-bottom: 0; // for use with heading elements\n font-size: $font-size-sm;\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-width * .85;\n vertical-align: $caret-width * .85;\n content: \"\";\n @if $direction == down {\n @include caret-down;\n } @else if $direction == up {\n @include caret-up;\n } @else if $direction == right {\n @include caret-right;\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-width * .85;\n vertical-align: $caret-width * .85;\n content: \"\";\n @include caret-left;\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n // Add width 1% and flex-basis auto to ensure that button will not wrap out\n // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.\n width: 1%;\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:last-child) { @include border-right-radius(0); }\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n font-size: $font-size-base; // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n font-size: $input-font-size-lg;\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n font-size: $input-font-size-sm;\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $input-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: $custom-control-indicator-bg-size;\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: $custom-checkbox-indicator-icon-checked;\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: $custom-checkbox-indicator-icon-indeterminate;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n &:indeterminate ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: $custom-radio-indicator-icon-checked;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: calc(#{(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2)} + #{$custom-control-indicator-border-width * 2});\n left: calc(#{-($custom-switch-width + $custom-control-gutter)} + #{$custom-control-indicator-border-width * 2});\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-background;\n background-color: $custom-select-bg;\n border: $custom-select-border-width solid $custom-select-border-color;\n @if $enable-rounded {\n border-radius: $custom-select-border-radius;\n } @else {\n border-radius: 0;\n }\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow;\n } @else {\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n opacity: 0;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n font-size: $custom-select-font-size-sm;\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n font-size: $custom-select-font-size-lg;\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: calc(#{$custom-range-thumb-height} + #{$custom-range-thumb-focus-box-shadow-width * 2});\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: none;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s or `<ul>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n\n @include hover-focus {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-item {\n margin-bottom: -$nav-tabs-border-width;\n }\n\n .nav-link {\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n > .container,\n > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n font-size: $navbar-brand-font-size;\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n font-size: $navbar-toggler-font-size;\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus {\n text-decoration: none;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .navbar-toggler elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n > .container,\n > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n > .container,\n > .container-fluid {\n flex-wrap: nowrap;\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-light-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-dark-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group:first-child {\n .list-group-item:first-child {\n @include border-top-radius($card-border-radius);\n }\n }\n\n > .list-group:last-child {\n .list-group-item:last-child {\n @include border-bottom-radius($card-border-radius);\n }\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n padding: $card-spacer-x;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n\n + .list-group {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n}\n\n.card-img {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-radius($card-inner-border-radius);\n}\n\n// Card image caps\n.card-img-top {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img-bottom {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n display: flex;\n flex-direction: column;\n\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n display: flex;\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n display: flex;\n flex-direction: column;\n\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:first-child {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n border-bottom-right-radius: 0;\n }\n }\n\n &:last-child {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n border-bottom-left-radius: 0;\n }\n }\n\n &:only-child {\n @include border-radius($card-border-radius);\n\n .card-img-top,\n .card-header {\n @include border-top-radius($card-border-radius);\n }\n .card-img-bottom,\n .card-footer {\n @include border-bottom-radius($card-border-radius);\n }\n }\n\n &:not(:first-child):not(:last-child):not(:only-child) {\n @include border-radius(0);\n\n .card-img-top,\n .card-img-bottom,\n .card-header,\n .card-footer {\n @include border-radius(0);\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n .card {\n overflow: hidden;\n\n &:not(:first-of-type) {\n .card-header:first-child {\n border-radius: 0;\n }\n\n &:not(:last-of-type) {\n border-bottom: 0;\n border-radius: 0;\n }\n }\n\n &:first-of-type {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n }\n\n &:last-of-type {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n .card-header {\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n display: inline-block; // Suppress underlining of the separator in modern browsers\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: $breadcrumb-divider;\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 2;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .page-link elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 1;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n font-size: $font-size;\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n font-size: $badge-font-size;\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n\n @at-root a#{&} {\n @include hover-focus {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","@keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n font-size: $progress-font-size;\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes $progress-bar-animation-timing;\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus {\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -$list-group-border-width;\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius($list-group-border-radius);\n }\n\n &:last-child {\n margin-bottom: 0;\n @include border-bottom-radius($list-group-border-radius);\n }\n\n @include hover-focus {\n z-index: 1; // Place hover/active items above their siblings for proper border styling\n text-decoration: none;\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n .list-group-item {\n border-right: 0;\n border-left: 0;\n @include border-radius(0);\n\n &:last-child {\n margin-bottom: -$list-group-border-width;\n }\n }\n\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n\n &:last-child {\n .list-group-item:last-child {\n margin-bottom: 0;\n border-bottom: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n font-size: $close-font-size;\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus {\n opacity: .75;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .close elements\n cursor: pointer;\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n appearance: none;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n max-width: $toast-max-width;\n overflow: hidden; // cheap rounded corners on nested items\n font-size: $toast-font-size; // knock it down to 14px\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n border-radius: $toast-border-radius;\n box-shadow: $toast-box-shadow;\n backdrop-filter: blur(10px);\n opacity: 0;\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - (#{$modal-dialog-margin} * 2));\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: calc(100vh - (#{$modal-dialog-margin} * 2));\n content: \"\";\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when should there be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-border-radius);\n\n // Easily place margin between footer elements\n > :not(:first-child) { margin-left: .25rem; }\n > :not(:last-child) { margin-right: .25rem; }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-centered {\n min-height: calc(100% - (#{$modal-dialog-margin-y-sm-up} * 2));\n\n &::before {\n height: calc(100vh - (#{$modal-dialog-margin-y-sm-up} * 2));\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n font-size: $tooltip-font-size;\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start; // stylelint-disable-line declaration-block-no-duplicate-properties\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n font-size: $popover-font-size;\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $border-radius-lg;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n .arrow {\n bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n }\n\n .arrow::before,\n .arrow::after {\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n }\n\n .arrow::before {\n bottom: 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n bottom: $popover-border-width;\n border-top-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n .arrow {\n left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n }\n\n .arrow::before,\n .arrow::after {\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n }\n\n .arrow::before {\n left: 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n left: $popover-border-width;\n border-right-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n .arrow {\n top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n }\n\n .arrow::before,\n .arrow::after {\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n }\n\n .arrow::before {\n top: 0;\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n top: $popover-border-width;\n border-bottom-color: $popover-arrow-color;\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n .arrow {\n right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n }\n\n .arrow::before,\n .arrow::after {\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n }\n\n .arrow::before {\n right: 0;\n border-left-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n right: $popover-border-width;\n border-left-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n font-size: $font-size-base;\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});\n @include border-top-radius($offset-border-width);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(0s $carousel-transition-duration opacity);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n.carousel-control-prev-icon {\n background-image: $carousel-control-prev-icon-bg;\n}\n.carousel-control-next-icon {\n background-image: $carousel-control-next-icon-bg;\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus {\n background-color: darken($color, 10%) !important;\n }\n }\n}\n\n@mixin bg-gradient-variant($parent, $color) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded {\n border-radius: $border-radius !important;\n}\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .d#{$infix}-none { display: none !important; }\n .d#{$infix}-inline { display: inline !important; }\n .d#{$infix}-inline-block { display: inline-block !important; }\n .d#{$infix}-block { display: block !important; }\n .d#{$infix}-table { display: table !important; }\n .d#{$infix}-table-row { display: table-row !important; }\n .d#{$infix}-table-cell { display: table-cell !important; }\n .d#{$infix}-flex { display: flex !important; }\n .d#{$infix}-inline-flex { display: inline-flex !important; }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { @include float-left; }\n .float#{$infix}-right { @include float-right; }\n .float#{$infix}-none { @include float-none; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@mixin float-left {\n float: left !important;\n}\n@mixin float-right {\n float: right !important;\n}\n@mixin float-none {\n float: none !important;\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://a11yproject.com/posts/how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate; }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color) {\n #{$parent} {\n color: $color !important;\n }\n a#{$parent} {\n @include hover-focus {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @if ($ignore-warning != true) {\n @warn \"The `text-hide()` mixin has been deprecated as of v4.1.0. It will be removed entirely in v5.\";\n }\n}\n","//\n// Visibility utilities\n//\n\n.visible {\n @include invisible(visible);\n}\n\n.invisible {\n @include invisible(hidden);\n}\n","// stylelint-disable declaration-no-important\n\n// Visibility\n\n@mixin invisible($visibility) {\n visibility: $visibility !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file diff --git a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css b/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css deleted file mode 100644 index edd61c64cb..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css +++ /dev/null @@ -1,3 +0,0 @@ -body{background-color:#323238;color:#eeeeee}.pane{display:none}.dark>.list-group-item{background:#454747}#output{background:#212121;color:#aaaaaa;font-family:monospace;padding:2em;font-weight:bold;min-height:6em;margin-top:1em}.small-font{font-size:0.85em} - -/*# sourceMappingURL=renamer.min.css.map */ \ No newline at end of file diff --git a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css.map b/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css.map deleted file mode 100644 index f21fefc948..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.min.css.map +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": 3, - "file": "renamer.min.css", - "sources": [ - "renamer.scss" - ], - "names": [], - "mappings": "AAAA,AAAA,IAAI,AAAC,CACH,gBAAgB,CAAE,OAAO,CACzB,KAAK,CAAE,OAAO,CACf,AAED,AAAA,KAAK,AAAC,CACJ,OAAO,CAAE,IAAI,CACd,AAED,AAAA,KAAK,CAAG,gBAAgB,AAAC,CACvB,UAAU,CAAE,OAAO,CACpB,AAED,AAAA,OAAO,AAAC,CACN,UAAU,CAAE,OAAO,CACnB,KAAK,CAAE,OAAO,CACd,WAAW,CAAE,SAAS,CACtB,OAAO,CAAE,GAAG,CACZ,WAAW,CAAE,IAAI,CACjB,UAAU,CAAE,GAAG,CACf,UAAU,CAAE,GAAG,CAChB,AAED,AAAA,WAAW,AAAC,CACV,SAAS,CAAE,MAAM,CAClB" -} \ No newline at end of file diff --git a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.scss b/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.scss deleted file mode 100644 index fd19266a9b..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/css/renamer.scss +++ /dev/null @@ -1,26 +0,0 @@ -body { - background-color: #323238; - color: #eeeeee; -} - -.pane { - display: none; -} - -.dark > .list-group-item { - background: #454747; -} - -#output { - background: #212121; - color: #aaaaaa; - font-family: monospace; - padding: 2em; - font-weight: bold; - min-height: 6em; - margin-top: 1em; -} - -.small-font { - font-size: 0.85em; -} diff --git a/pype/hosts/premiere/extensions/com.pype.rename/index.html b/pype/hosts/premiere/extensions/com.pype.rename/index.html deleted file mode 100644 index 08756e2829..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/index.html +++ /dev/null @@ -1,205 +0,0 @@ -<!DOCTYPE html> -<!-- - - -. == [ part 0f PyPE CluB ] == .- -_______________.___._____________________ -\______ \__ | |\______ \_ _____/ - | ___// | | | ___/| __)_ - | | \____ | | | | \ - |____| / ______| |____| /_______ / - \/ \/ - .. __/ CliP R3N4M3R \__ .. - ---> -<html lang="en"> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <title>Pype Renamer - - - - - - - - - - - - - -
-
Clip renamer
- - -
-
-
- -
Sequential Rename with Hierarchy
-
-
- Folder -
- -
-
-
- Episode -
- -
-
-
- Sequence -
- -
-
- - -
-

Use tokens of above fields to reference its value.

-
-
- Pattern -
- -
-
-
- Start # / Increment -
- - -
- -
-
- -
Sequential Rename
-
-
- Pattern -
- -
-
-
- Start # / Increment -
- - -
-
- - -
-
- -
- -
Simple Rename
-

Use {shot} token to reference current clip name. -

-
- New Name -
- -
-
- -
- -
Find and replace
-
-
- Find -
- - -
- Replace -
-
-
- -
- -
Match sequence
-

Not implemented yet.

- -
-
- -
Clip Rename
-

This will rename clip to its filename

- -
-
- -
Change Case
-
-
- - -
- -
-
-
- - -
-
- -
- - - - diff --git a/pype/hosts/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx b/pype/hosts/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx deleted file mode 100644 index 6a34893a82..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx +++ /dev/null @@ -1,2379 +0,0 @@ -/************************************************************************* - * ADOBE CONFIDENTIAL - * ___________________ - * - * Copyright 2014 Adobe - * All Rights Reserved. - * - * NOTICE: Adobe permits you to use, modify, and distribute this file in - * accordance with the terms of the Adobe license agreement accompanying - * it. If you have received this file from a source other than Adobe, - * then your use, modification, or distribution of it requires the prior - * written permission of Adobe. - **************************************************************************/ -//include "PPro_API_Constants.jsx" - -$._PPP_ = { - - createDeepFolderStructure: function (foldersArray, maxDepth) { - if (typeof foldersArray !== 'object' || foldersArray.length <= 0) { - throw new Error('No valid folders array was provided!'); - } - - // if the first folder already exists, throw error - for (var i = 0; i < app.project.rootItem.children.numItems; i++) { - var curChild = app.project.rootItem.children[i]; - if (curChild.type === ProjectItemType.BIN && curChild.name === foldersArray[0]) { - throw new Error('Folder with name "' + curChild.name + '" already exists!'); - } - } - - // create the deep folder structure - var currentBin = app.project.rootItem.createBin(foldersArray[0]); - for (var m = 1; m < foldersArray.length && m < maxDepth; i++) { - currentBin = currentBin.createBin(foldersArray[i]); - } - }, - - getVersionInfo: function () { - return 'PPro ' + app.version + 'x' + app.build; - }, - - getUserName: function () { - var homeDir = new File('~/'); - var userName = homeDir.displayName; - homeDir.close(); - return userName; - }, - - updateGrowingFile: function () { - var numItems = app.project.rootItem.children.numItems; - for (var i = 0; i < numItems; i++) { - var currentItem = app.project.rootItem.children[i]; - if (currentItem) { - currentItem.refreshMedia(); - } - } - }, - - getSep: function () { - if (Folder.fs == 'Macintosh') { - return '/'; - } else { - return '\\'; - } - }, - - saveProject: function () { - app.project.save(); - }, - - exportCurrentFrameAsPNG: function () { - app.enableQE(); - var activeSequence = qe.project.getActiveSequence(); // note: make sure a sequence is active in PPro UI - if (activeSequence) { - // Create a file name based on timecode of frame. - var time = activeSequence.CTI.timecode; // CTI = Current Time Indicator. - var removeThese = /:|;/ig; // Why? Because Windows chokes on colons. - time = time.replace(removeThese, '_'); - var outputPath = new File("~/Desktop"); - var outputFileName = outputPath.fsName + $._PPP_.getSep() + time + '___' + activeSequence.name; - activeSequence.exportFramePNG(time, outputFileName); - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - renameFootage: function () { - var item = app.project.rootItem.children[0]; // assumes the zero-th item in the project is footage. - if (item) { - item.name = item.name + ", updated by PProPanel."; - } else { - $._PPP_.updateEventPanel("No project items found."); - } - }, - - getActiveSequenceName: function () { - if (app.project.activeSequence) { - return app.project.activeSequence.name; - } else { - return "No active sequence."; - } - }, - - projectPanelSelectionChanged: function (projectItems, viewID) { - - var remainingArgs = projectItems.length; - var message = ""; - - if (remainingArgs) { - var message = remainingArgs + " items selected: "; - var view = viewID; - - // Concatenate selected project item names, into message. - for (var i = 0; i < projectItems.length; i++) { - message += projectItems[i].name; - remainingArgs--; - if (remainingArgs > 1) { - message += ', '; - } - if (remainingArgs === 1) { - message += ", and "; - } - if (remainingArgs === 0) { - message += "."; - } - } - } else { - message = '0 items selected.'; - } - app.setSDKEventMessage(message, 'info'); - }, - - registerProjectPanelSelectionChangedFxn: function () { - var success = app.bind("onSourceClipSelectedInProjectPanel", $._PPP_.projectPanelSelectionChanged); - }, - - saveCurrentProjectLayout: function () { - var currentProjPanelDisplay = app.project.getProjectPanelMetadata(); - if (currentProjPanelDisplay) { - var outFileName = 'Previous_Project_Panel_Display_Settings.xml'; - var actualProjectPath = new File(app.project.path); - var projDir = actualProjectPath.parent; - if (actualProjectPath) { - var completeOutputPath = projDir + $._PPP_.getSep() + outFileName; - var outFile = new File(completeOutputPath); - if (outFile) { - outFile.encoding = "UTF8"; - outFile.open("w", "TEXT", "????"); - outFile.write(currentProjPanelDisplay); - $._PPP_.updateEventPanel("Saved layout to next to the project."); - outFile.close(); - } - actualProjectPath.close(); - } - } else { - $._PPP_.updateEventPanel("Could not retrieve current project layout."); - } - }, - - setProjectPanelMeta: function () { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "XML files:*.xml"; - } - var fileToOpen = File.openDialog("Choose Project panel layout to open.", - filterString, - false); - if (fileToOpen) { - if (fileToOpen.fsName.indexOf('.xml')) { // We should really be more careful, but hey, it says it's XML! - fileToOpen.encoding = "UTF8"; - fileToOpen.open("r", "TEXT", "????"); - var fileContents = fileToOpen.read(); - if (fileContents) { - var setResult = app.project.setProjectPanelMetadata(fileContents); - if (setResult) { - $._PPP_.updateEventPanel("Could not update layout using " + fileToOpen.filename + "."); - } else { - $._PPP_.updateEventPanel("Updated layout from .xml file."); - } - } - } - } else { - $._PPP_.updateEventPanel("No valid layout file chosen."); - } - }, - - exportSequenceAsPrProj: function () { - var activeSequence = app.project.activeSequence; - if (activeSequence) { - var startTimeOffset = activeSequence.zeroPoint; - var prProjExtension = '.prproj'; - var outputName = activeSequence.name; - var outFolder = Folder.selectDialog(); - - if (outFolder) { - var completeOutputPath = outFolder.fsName + - $._PPP_.getSep() + - outputName + - prProjExtension; - - app.project.activeSequence.exportAsProject(completeOutputPath); - - $._PPP_.updateEventPanel("Exported " + app.project.activeSequence.name + " to " + completeOutputPath + "."); - } else { - $._PPP_.updateEventPanel("Could not find or create output folder."); - } - - // Here's how to import N sequences from a project. - // - // var seqIDsToBeImported = new Array; - // seqIDsToBeImported[0] = ID1; - // ... - // seqIDsToBeImported[N] = IDN; - // - //app.project.importSequences(pathToPrProj, seqIDsToBeImported); - - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - createSequenceMarkers: function () { - var activeSequence = app.project.activeSequence; - if (activeSequence) { - var markers = activeSequence.markers; - if (markers) { - var numMarkers = markers.numMarkers; - if (numMarkers > 0) { - var marker_index = 1; - for (var current_marker = markers.getFirstMarker(); current_marker !== undefined; current_marker = markers.getNextMarker(current_marker)) { - if (current_marker.name !== "") { - $._PPP_.updateEventPanel('Marker ' + marker_index + ' name = ' + current_marker.name + '.'); - } else { - $._PPP_.updateEventPanel('Marker ' + marker_index + ' has no name.'); - } - - if (current_marker.end.seconds > 0) { - $._PPP_.updateEventPanel('Marker ' + marker_index + ' duration = ' + (current_marker.end.seconds - current_marker.start.seconds) + ' seconds.'); - } else { - $._PPP_.updateEventPanel('Marker ' + marker_index + ' has no duration.'); - } - $._PPP_.updateEventPanel('Marker ' + marker_index + ' starts at ' + current_marker.start.seconds + ' seconds.'); - marker_index = marker_index + 1; - } - } - } - - var newCommentMarker = markers.createMarker(12.345); - newCommentMarker.name = 'Marker created by PProPanel.'; - newCommentMarker.comments = 'Here are some comments, inserted by PProPanel.'; - newCommentMarker.end = 15.6789; - - var newWebMarker = markers.createMarker(14.345); - newWebMarker.name = 'Web marker created by PProPanel.'; - newWebMarker.comments = 'Here are some comments, inserted by PProPanel.'; - newWebMarker.end = 17.6789; - newWebMarker.setTypeAsWebLink("http://www.adobe.com", "frame target"); - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - exportFCPXML: function () { - if (app.project.activeSequence) { - var projPath = new File(app.project.path); - var parentDir = projPath.parent; - var outputName = app.project.activeSequence.name; - var xmlExtension = '.xml'; - var outputPath = Folder.selectDialog("Choose the output directory"); - - if (outputPath) { - var completeOutputPath = outputPath.fsName + $._PPP_.getSep() + outputName + xmlExtension; - app.project.activeSequence.exportAsFinalCutProXML(completeOutputPath, 1); // 1 == suppress UI - var info = "Exported FCP XML for " + - app.project.activeSequence.name + - " to " + - completeOutputPath + - "."; - $._PPP_.updateEventPanel(info); - } else { - $._PPP_.updateEventPanel("No output path chosen."); - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - openInSource: function () { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - var fileToOpen = File.openDialog("Choose file to open.", - filterString, - false); - if (fileToOpen) { - app.sourceMonitor.openFilePath(fileToOpen.fsName); - app.sourceMonitor.play(1.73); // playback speed as float, 1.0 = normal speed forward - var position = app.sourceMonitor.getPosition(); // new in 13.0 - $._PPP_.updateEventPanel("Current Source monitor position: " + position.seconds + " seconds."); - fileToOpen.close(); - } else { - $._PPP_.updateEventPanel("No file chosen."); - } - }, - - searchForBinWithName: function (nameToFind) { - // deep-search a folder by name in project - var deepSearchBin = function (inFolder) { - if (inFolder && inFolder.name === nameToFind && inFolder.type === 2) { - return inFolder; - } else { - for (var i = 0; i < inFolder.children.numItems; i++) { - if (inFolder.children[i] && inFolder.children[i].type === 2) { - var foundBin = deepSearchBin(inFolder.children[i]); - if (foundBin) return foundBin; - } - } - } - return undefined; - }; - return deepSearchBin(app.project.rootItem); - }, - - importFiles: function () { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - if (app.project) { - var fileOrFilesToImport = File.openDialog("Choose files to import", // title - filterString, // filter available files? - true); // allow multiple? - if (fileOrFilesToImport) { - // We have an array of File objects; importFiles() takes an array of paths. - var importThese = []; - if (importThese) { - for (var i = 0; i < fileOrFilesToImport.length; i++) { - importThese[i] = fileOrFilesToImport[i].fsName; - } - app.project.importFiles(importThese, - 1, // suppress warnings - app.project.getInsertionBin(), - 0); // import as numbered stills - } - } else { - $._PPP_.updateEventPanel("No files to import."); - } - } - }, - - muteFun: function () { - if (app.project.activeSequence) { - for (var i = 0; i < app.project.activeSequence.audioTracks.numTracks; i++) { - var currentTrack = app.project.activeSequence.audioTracks[i]; - if (Math.random() > 0.5) { - currentTrack.setMute(!(currentTrack.isMuted())); - } - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - disableImportWorkspaceWithProjects: function () { - var prefToModify = 'FE.Prefs.ImportWorkspace'; - var appProperties = app.properties; - - if (appProperties) { - var propertyExists = app.properties.doesPropertyExist(prefToModify); - var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); - var propertyValue = app.properties.getProperty(prefToModify); - - appProperties.setProperty(prefToModify, false, 1); // optional 3rd param : 0 = non-persistent, 1 = persistent (default) - var safetyCheck = app.properties.getProperty(prefToModify); - if (safetyCheck != propertyValue) { - $._PPP_.updateEventPanel("Changed \'Import Workspaces with Projects\' from " + propertyValue + " to " + safetyCheck + "."); - } - } else { - $._PPP_.updateEventPanel("Properties not found."); - } - }, - - turnOffStartDialog: function () { - var prefToModify = 'MZ.Prefs.ShowQuickstartDialog'; - var appProperties = app.properties; - if (appProperties) { - var propertyExists = app.properties.doesPropertyExist(prefToModify); - var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); - var originalValue = app.properties.getProperty(prefToModify); - - appProperties.setProperty(prefToModify, false, 1, 1); // optional 4th param : 0 = non-persistent, 1 = persistent (default) - var safetyCheck = app.properties.getProperty(prefToModify); - if (safetyCheck != originalValue) { - $._PPP_.updateEventPanel("Start dialog now OFF. Enjoy!"); - } else { - $._PPP_.updateEventPanel("Start dialog was already OFF."); - } - } else { - $._PPP_.updateEventPanel("Properties not found."); - } - }, - - replaceMedia: function () { - - // Note: This method of changing paths for projectItems is from the time - // before PPro supported full-res AND proxy paths for each projectItem. - // This can still be used, and will change the hi-res projectItem path, but - // if your panel supports proxy workflows, it should rely instead upon - // projectItem.setProxyPath() instead. - - var firstProjectItem = app.project.rootItem.children[0]; - if (firstProjectItem) { - if (firstProjectItem.canChangeMediaPath()) { - - // NEW in 9.0: setScaleToFrameSize() ensures that for all clips created from this footage, - // auto scale to frame size will be ON, regardless of the current user preference. - // This is important for proxy workflows, to avoid mis-scaling upon replacement. - - // Addendum: This setting will be in effect the NEXT time the projectItem is added to a - // sequence; it will not affect or reinterpret clips from this projectItem, already in - // sequences. - - firstProjectItem.setScaleToFrameSize(); - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - var replacementMedia = File.openDialog("Choose new media file, for " + - firstProjectItem.name, - filterString, // file filter - false); // allow multiple? - - if (replacementMedia) { - var suppressWarnings = true; - firstProjectItem.name = replacementMedia.name + ", formerly known as " + firstProjectItem.name; - firstProjectItem.changeMediaPath(replacementMedia.fsName, suppressWarnings); // new in 12.1 - replacementMedia.close(); - } - } else { - $._PPP_.updateEventPanel("Couldn't change path of " + firstProjectItem.name + "."); - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - }, - - openProject: function () { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "Premiere Pro project files:*.prproj"; - } - var projToOpen = File.openDialog("Choose project:", - filterString, - false); - if ((projToOpen) && projToOpen.exists) { - app.openDocument(projToOpen.fsName, - 1, // suppress 'Convert Project' dialogs? - 1, // suppress 'Locate Files' dialogs? - 1); // suppress warning dialogs? - projToOpen.close(); - } - }, - - exportFramesForMarkers: function () { - app.enableQE(); - var activeSequence = app.project.activeSequence; - if (activeSequence) { - var markers = activeSequence.markers; - var markerCount = markers.numMarkers; - if (markerCount) { - var firstMarker = markers.getFirstMarker(); - activeSequence.setPlayerPosition(firstMarker.start.ticks); - $._PPP_.exportCurrentFrameAsPNG(); - - var previousMarker = 0; - if (firstMarker) { - for (var i = 0; i < markerCount; i++) { - if (i === 0) { - currentMarker = markers.getNextMarker(firstMarker); - } else { - currentMarker = markers.getNextMarker(previousMarker); - } - if (currentMarker) { - activeSequence.setPlayerPosition(currentMarker.start.ticks); - previousMarker = currentMarker; - $._PPP_.exportCurrentFrameAsPNG(); - } - } - } - } else { - $._PPP_.updateEventPanel("No markers applied to " + activeSequence.name + "."); - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - createSequence: function (name) { - var someID = "xyz123"; - var seqName = prompt('Name of sequence?', '<<>>', 'Sequence Naming Prompt'); - app.project.createNewSequence(seqName, someID); - }, - - createSequenceFromPreset: function (presetPath) { - app.enableQE(); - var seqName = prompt('Name of sequence?', '<<>>', 'Sequence Naming Prompt'); - if (seqName) { - qe.project.newSequence(seqName, presetPath); - } - }, - - transcode: function (outputPresetPath) { - app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); - app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError); - app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress); - app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued); - app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); - - var projRoot = app.project.rootItem.children; - - if (projRoot.numItems) { - var firstProjectItem = app.project.rootItem.children[0]; - if (firstProjectItem) { - - app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. - - var fileOutputPath = Folder.selectDialog("Choose the output directory"); - if (fileOutputPath) { - var outputName = firstProjectItem.name.search('[.]'); - if (outputName == -1) { - outputName = firstProjectItem.name.length; - } - outFileName = firstProjectItem.name.substr(0, outputName); - outFileName = outFileName.replace('/', '-'); - var completeOutputPath = fileOutputPath.fsName + $._PPP_.getSep() + outFileName + '.mxf'; - var removeFromQueue = true; - var rangeToEncode = app.encoder.ENCODE_IN_TO_OUT; - app.encoder.encodeProjectItem(firstProjectItem, - completeOutputPath, - outputPresetPath, - rangeToEncode, - removeFromQueue); - app.encoder.startBatch(); - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - } else { - $._PPP_.updateEventPanel("Project is empty."); - } - }, - - transcodeExternal: function (outputPresetPath) { - app.encoder.launchEncoder(); - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - var fileToTranscode = File.openDialog("Choose file to open.", - filterString, - false); - if (fileToTranscode) { - var fileOutputPath = Folder.selectDialog("Choose the output directory"); - if (fileOutputPath) { - - var srcInPoint = 1.0; // encode start time at 1s (optional--if omitted, encode entire file) - var srcOutPoint = 3.0; // encode stop time at 3s (optional--if omitted, encode entire file) - var removeFromQueue = false; - - var result = app.encoder.encodeFile(fileToTranscode.fsName, - fileOutputPath.fsName, - outputPresetPath, - removeFromQueue, - srcInPoint, - srcOutPoint); - } - } - }, - - render: function (outputPresetPath) { - app.enableQE(); - var activeSequence = qe.project.getActiveSequence(); // we use a QE DOM function, to determine the output extension. - if (activeSequence) { - app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. - - var timeSecs = activeSequence.CTI.secs; // Just for reference, here's how to access the CTI - var timeFrames = activeSequence.CTI.frames; // (Current Time Indicator), for the active sequence. - var timeTicks = activeSequence.CTI.ticks; - var timeString = activeSequence.CTI.timecode; - - var seqInPoint = app.project.activeSequence.getInPoint(); // new in 9.0 - var seqOutPoint = app.project.activeSequence.getOutPoint(); // new in 9.0 - - var seqInPointAsTime = app.project.activeSequence.getInPointAsTime(); // new in 12.0 - var seqOutPointAsTime = app.project.activeSequence.getOutPointAsTime(); // new in 12.0 - - var projPath = new File(app.project.path); - var outputPath = Folder.selectDialog("Choose the output directory"); - - if ((outputPath) && projPath.exists) { - var outPreset = new File(outputPresetPath); - if (outPreset.exists === true) { - var outputFormatExtension = activeSequence.getExportFileExtension(outPreset.fsName); - if (outputFormatExtension) { - var outputFilename = activeSequence.name + '.' + outputFormatExtension; - - var fullPathToFile = outputPath.fsName + - $._PPP_.getSep() + - activeSequence.name + - "." + - outputFormatExtension; - - var outFileTest = new File(fullPathToFile); - - if (outFileTest.exists) { - var destroyExisting = confirm("A file with that name already exists; overwrite?", false, "Are you sure...?"); - if (destroyExisting) { - outFileTest.remove(); - outFileTest.close(); - } - } - - app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); - app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError); - app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress); - app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued); - app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); - - - // use these 0 or 1 settings to disable some/all metadata creation. - - app.encoder.setSidecarXMPEnabled(0); - app.encoder.setEmbeddedXMPEnabled(0); - - /* - - For reference, here's how to export from within PPro (blocking further user interaction). - - var seq = app.project.activeSequence; - - if (seq) { - seq.exportAsMediaDirect(fullPathToFile, - outPreset.fsName, - app.encoder.ENCODE_WORKAREA); - - Bonus: Here's how to compute a sequence's duration, in ticks. 254016000000 ticks/second. - var sequenceDuration = app.project.activeSequence.end - app.project.activeSequence.zeroPoint; - } - - */ - - var jobID = app.encoder.encodeSequence(app.project.activeSequence, - fullPathToFile, - outPreset.fsName, - app.encoder.ENCODE_WORKAREA, - 1); // Remove from queue upon successful completion? - $._PPP_.updateEventPanel('jobID = ' + jobID); - outPreset.close(); - } - } else { - $._PPP_.updateEventPanel("Could not find output preset."); - } - } else { - $._PPP_.updateEventPanel("Could not find/create output path."); - } - projPath.close(); - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - saveProjectCopy: function () { - var sessionCounter = 1; - var originalPath = app.project.path; - var outputPath = Folder.selectDialog("Choose the output directory"); - - if (outputPath) { - var absPath = outputPath.fsName; - var outputName = String(app.project.name); - var array = outputName.split('.', 2); - - outputName = array[0] + sessionCounter + '.' + array[1]; - sessionCounter++; - - var fullOutPath = absPath + $._PPP_.getSep() + outputName; - - app.project.saveAs(fullOutPath); - - for (var a = 0; a < app.projects.numProjects; a++) { - var currentProject = app.projects[a]; - if (currentProject.path === fullOutPath) { - app.openDocument(originalPath); // Why first? So we don't frighten the user by making PPro's window disappear. :) - currentProject.closeDocument(); - } - } - } else { - $._PPP_.updateEventPanel("No output path chosen."); - } - }, - - mungeXMP: function () { - var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. - if (projectItem) { - if (ExternalObject.AdobeXMPScript === undefined) { - ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); - } - if (ExternalObject.AdobeXMPScript !== undefined) { // safety-conscious! - - var xmpBlob = projectItem.getXMPMetadata(); - var xmp = new XMPMeta(xmpBlob); - var oldSceneVal = ""; - var oldDMCreatorVal = ""; - - if (xmp.doesPropertyExist(XMPConst.NS_DM, "scene") === true) { - var myScene = xmp.getProperty(XMPConst.NS_DM, "scene"); - oldSceneVal = myScene.value; - } - - if (xmp.doesPropertyExist(XMPConst.NS_DM, "creator") === true) { - var myCreator = xmp.getProperty(XMPConst.NS_DM, "creator"); - oldCreatorVal = myCreator.value; - } - - // Regardless of whether there WAS scene or creator data, set scene and creator data. - - xmp.setProperty(XMPConst.NS_DM, "scene", oldSceneVal + " Added by PProPanel sample!"); - xmp.setProperty(XMPConst.NS_DM, "creator", oldDMCreatorVal + " Added by PProPanel sample!"); - - // That was the NS_DM creator; here's the NS_DC creator. - - var creatorProp = "creator"; - var containsDMCreatorValue = xmp.doesPropertyExist(XMPConst.NS_DC, creatorProp); - var numCreatorValuesPresent = xmp.countArrayItems(XMPConst.NS_DC, creatorProp); - var CreatorsSeparatedBy4PoundSigns = ""; - - if (numCreatorValuesPresent > 0) { - for (var z = 0; z < numCreatorValuesPresent; z++) { - CreatorsSeparatedBy4PoundSigns = CreatorsSeparatedBy4PoundSigns + xmp.getArrayItem(XMPConst.NS_DC, creatorProp, z + 1); - CreatorsSeparatedBy4PoundSigns = CreatorsSeparatedBy4PoundSigns + "####"; - } - $._PPP_.updateEventPanel(CreatorsSeparatedBy4PoundSigns); - - if (confirm("Replace previous?", false, "Replace existing Creator?")) { - xmp.deleteProperty(XMPConst.NS_DC, "creator"); - } - xmp.appendArrayItem(XMPConst.NS_DC, // If no values exist, appendArrayItem will create a value. - creatorProp, - numCreatorValuesPresent + " creator values were already present.", - null, - XMPConst.ARRAY_IS_ORDERED); - - } else { - - xmp.appendArrayItem(XMPConst.NS_DC, - creatorProp, - "PProPanel wrote the first value into NS_DC creator field.", - null, - XMPConst.ARRAY_IS_ORDERED); - } - var xmpAsString = xmp.serialize(); // either way, serialize and write XMP. - projectItem.setXMPMetadata(xmpAsString); - } - } else { - $._PPP_.updateEventPanel("Project item required."); - } - }, - - getProductionByName: function (nameToGet) { - var production; - for (var i = 0; i < productionList.numProductions; i++) { - var currentProduction = productionList[i]; - - if (currentProduction.name == nameToGet) { - production = currentProduction; - } - } - return production; - }, - - pokeAnywhere: function () { - var token = app.anywhere.getAuthenticationToken(); - var productionList = app.anywhere.listProductions(); - var isProductionOpen = app.anywhere.isProductionOpen(); - if (isProductionOpen === true) { - var sessionURL = app.anywhere.getCurrentEditingSessionURL(); - var selectionURL = app.anywhere.getCurrentEditingSessionSelectionURL(); - var activeSequenceURL = app.anywhere.getCurrentEditingSessionActiveSequenceURL(); - - var theOneIAskedFor = $._PPP_.getProductionByName("test"); - - if (theOneIAskedFor) { - var out = theOneIAskedFor.name + ", " + theOneIAskedFor.description; - $._PPP_.updateEventPanel("Found: " + out); // todo: put useful code here. - } - } else { - $._PPP_.updateEventPanel("No Production open."); - } - }, - - dumpOMF: function () { - var activeSequence = app.project.activeSequence; - if (activeSequence) { - var outputPath = Folder.selectDialog("Choose the output directory"); - if (outputPath) { - var absPath = outputPath.fsName; - var outputName = String(activeSequence.name) + '.omf'; - var fullOutPathWithName = absPath + $._PPP_.getSep() + outputName; - - app.project.exportOMF(app.project.activeSequence, // sequence - fullOutPathWithName, // output file path - 'OMFTitle', // OMF title - 48000, // sample rate (48000 or 96000) - 16, // bits per sample (16 or 24) - 1, // audio encapsulated flag (1 : yes or 0 : no) - 0, // audio file format (0 : AIFF or 1 : WAV) - 0, // trim audio files (0 : no or 1 : yes) - 0, // handle frames (if trim is 1, handle frames from 0 to 1000) - 0); // include pan flag (0 : no or 1 : yes) - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - addClipMarkers: function () { - if (app.project.rootItem.children.numItems > 0) { - var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. - if (projectItem) { - if (projectItem.type == ProjectItemType.CLIP || projectItem.type == ProjectItemType.FILE) { - - markers = projectItem.getMarkers(); - - if (markers) { - var num_markers = markers.numMarkers; - var new_marker = markers.createMarker(12.345); - var guid = new_marker.guid; // new in 11.1 - - new_marker.name = 'Marker created by PProPanel.'; - new_marker.comments = 'Here are some comments, inserted by PProPanel.'; - new_marker.end = 15.6789; - - //default marker type == comment. To change marker type, call one of these: - - // new_marker.setTypeAsChapter(); - // new_marker.setTypeAsWebLink(); - // new_marker.setTypeAsSegmentation(); - // new_marker.setTypeAsComment(); - } - } else { - $._PPP_.updateEventPanel("Can only add markers to footage items."); - } - } else { - $._PPP_.updateEventPanel("Could not find first projectItem."); - } - } else { - $._PPP_.updateEventPanel("Project is empty."); - } - }, - - modifyProjectMetadata: function () { - var kPProPrivateProjectMetadataURI = "http://ns.adobe.com/premierePrivateProjectMetaData/1.0/"; - - var namefield = "Column.Intrinsic.Name"; - var tapename = "Column.Intrinsic.TapeName"; - var desc = "Column.PropertyText.Description"; - var logNote = "Column.Intrinsic.LogNote"; - var newField = "ExampleFieldName"; - - if (app.isDocumentOpen()) { - var projectItem = app.project.rootItem.children[0]; // just grabs first projectItem. - if (projectItem) { - if (ExternalObject.AdobeXMPScript === undefined) { - ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); - } - if (ExternalObject.AdobeXMPScript !== undefined) { // safety-conscious! - var projectMetadata = projectItem.getProjectMetadata(); - var successfullyAdded = app.project.addPropertyToProjectMetadataSchema(newField, "ExampleFieldLabel", 2); - - var xmp = new XMPMeta(projectMetadata); - var obj = xmp.dumpObject(); - - // var aliases = xmp.dumpAliases(); - - var namespaces = XMPMeta.dumpNamespaces(); - var found_name = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, namefield); - var found_tapename = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, tapename); - var found_desc = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, desc); - var found_custom = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, newField); - var foundLogNote = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, logNote); - var oldLogValue = ""; - var appendThis = "This log note inserted by PProPanel."; - var appendTextWasActuallyNew = false; - - if (foundLogNote) { - var oldLogNote = xmp.getProperty(kPProPrivateProjectMetadataURI, logNote); - if (oldLogNote) { - oldLogValue = oldLogNote.value; - } - } - - xmp.setProperty(kPProPrivateProjectMetadataURI, tapename, "***TAPENAME***"); - xmp.setProperty(kPProPrivateProjectMetadataURI, desc, "***DESCRIPTION***"); - xmp.setProperty(kPProPrivateProjectMetadataURI, namefield, "***NEWNAME***"); - xmp.setProperty(kPProPrivateProjectMetadataURI, newField, "PProPanel set this, using addPropertyToProjectMetadataSchema()."); - - - var array = []; - array[0] = tapename; - array[1] = desc; - array[2] = namefield; - array[3] = newField; - - var concatenatedLogNotes = ""; - - if (oldLogValue != appendThis) { // if that value is not exactly what we were going to add - if (oldLogValue.length > 0) { // if we have a valid value - concatenatedLogNotes += "Previous log notes: " + oldLogValue + " |||| "; - } - concatenatedLogNotes += appendThis; - xmp.setProperty(kPProPrivateProjectMetadataURI, logNote, concatenatedLogNotes); - array[4] = logNote; - } - - var str = xmp.serialize(); - projectItem.setProjectMetadata(str, array); - - // test: is it in there? - - var newblob = projectItem.getProjectMetadata(); - var newXMP = new XMPMeta(newblob); - var foundYet = newXMP.doesPropertyExist(kPProPrivateProjectMetadataURI, newField); - - if (foundYet) { - $._PPP_.updateEventPanel("PProPanel successfully added a field to the project metadata schema, and set a value for it."); - } - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - } - }, - - updatePAR: function () { - var item = app.project.rootItem.children[0]; - if (item) { - if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)) { - // If there is an item, and it's either a clip or file... - item.setOverridePixelAspectRatio(185, 100); // anamorphic is BACK! ;) - } else { - $._PPP_.updateEventPanel('You cannot override the PAR of bins or sequences.'); - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - }, - - getnumAEProjectItems: function () { - var bt = new BridgeTalk(); - bt.target = 'aftereffects'; - bt.body = //'$._PPP_.updateEventPanel("Items in AE project: " + app.project.rootFolder.numItems);app.quit();'; - 'alert("Items in AE project: " + app.project.rootFolder.numItems);app.quit();'; - bt.send(); - }, - - updateEventPanel: function (message) { - app.setSDKEventMessage(message, 'info'); - //app.setSDKEventMessage('Here is some information.', 'info'); - //app.setSDKEventMessage('Here is a warning.', 'warning'); - //app.setSDKEventMessage('Here is an error.', 'error'); // Very annoying; use sparingly. - }, - - walkAllBinsForFootage: function (parentItem, outPath) { - for (var j = 0; j < parentItem.children.numItems; j++) { - var currentChild = parentItem.children[j]; - if (currentChild) { - if (currentChild.type == ProjectItemType.BIN) { - $._PPP_.walkAllBinsForFootage(currentChild, outPath); // warning; recursion! - } else { - $._PPP_.dumpProjectItemXMP(currentChild, outPath); - } - } - } - }, - - searchBinForProjItemByName: function (i, containingBin, nameToFind) { - for (var j = i; j < containingBin.children.numItems; j++) { - var currentChild = containingBin.children[j]; - if (currentChild) { - if (currentChild.type == ProjectItemType.BIN) { - return $._PPP_.searchBinForProjItemByName(j, currentChild, nameToFind); // warning; recursion! - } else { - if (currentChild.name == nameToFind) { - return currentChild; - } else { - currentChild = currentItem.children[j + 1]; - if (currentChild) { - return $._PPP_.searchBinForProjItemByName(0, currentChild, nameToFind); - } - } - } - } - } - }, - - dumpProjectItemXMP: function (projectItem, outPath) { - var xmpBlob = projectItem.getXMPMetadata(); - var outFileName = projectItem.name + '.xmp'; - var completeOutputPath = outPath + $._PPP_.getSep() + outFileName; - var outFile = new File(completeOutputPath); - - var isThisASequence = projectItem.isSequence(); - - if (outFile) { - outFile.encoding = "UTF8"; - outFile.open("w", "TEXT", "????"); - outFile.write(xmpBlob.toString()); - outFile.close(); - } - }, - - addSubClip: function () { - var startTime = new Time; - startTime.seconds = 0.0; - var endTime = new Time; - endTime.seconds = 3.21; - var hasHardBoundaries = 0; - var sessionCounter = 1; - var takeVideo = 1; // optional, defaults to 1 - var takeAudio = 1; // optional, defaults to 1 - var projectItem = app.project.rootItem.children[0]; // just grabs the first item - if (projectItem) { - if ((projectItem.type == ProjectItemType.CLIP) || (projectItem.type == ProjectItemType.FILE)) { - var newSubClipName = prompt('Name of subclip?', projectItem.name + '_' + sessionCounter, 'Name your subclip'); - - var newSubClip = projectItem.createSubClip(newSubClipName, - startTime, - endTime, - hasHardBoundaries, - takeVideo, - takeAudio); - - if (newSubClip) { - newSubClip.setStartTime(12.345); - } - } else { - $._PPP_.updateEventPanel("Could not sub-clip " + projectItem.name + "."); - } - } else { - $._PPP_.updateEventPanel("No project item found."); - } - }, - - dumpXMPFromAllProjectItems: function () { - var numItemsInRoot = app.project.rootItem.children.numItems; - if (numItemsInRoot > 0) { - var outPath = Folder.selectDialog("Choose the output directory"); - if (outPath) { - for (var i = 0; i < numItemsInRoot; i++) { - var currentItem = app.project.rootItem.children[i]; - if (currentItem) { - if (currentItem.type == ProjectItemType.BIN) { - $._PPP_.walkAllBinsForFootage(currentItem, outPath.fsName); - } else { - $._PPP_.dumpProjectItemXMP(currentItem, outPath.fsName); - } - } - } - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - }, - - exportAAF: function () { - var sessionCounter = 1; - if (app.project.activeSequence) { - var outputPath = Folder.selectDialog("Choose the output directory"); - if (outputPath) { - var absPath = outputPath.fsName; - var outputName = String(app.project.name); - var array = outputName.split('.', 2); - outputName = array[0] + sessionCounter + '.' + array[1]; - - sessionCounter++; - var fullOutPath = absPath + $._PPP_.getSep() + outputName + '.aaf'; - //var optionalPathToOutputPreset = null; New in 11.0.0, you can specify an output preset. - - app.project.exportAAF(app.project.activeSequence, // which sequence - fullOutPath, // output path - 1, // mix down video? - 0, // explode to mono? - 96000, // sample rate - 16, // bits per sample - 0, // embed audio? - 0, // audio file format? 0 = aiff, 1 = wav - 0, // trim sources? - 0 - /*, // number of 'handle' frames - optionalPathToOutputPreset*/ - ); // optional; .epr file to use - } else { - $._PPP_.updateEventPanel("Couldn't create AAF output."); - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - setScratchDisk: function () { - var scratchPath = Folder.selectDialog("Choose new scratch disk directory"); - if ((scratchPath) && scratchPath.exists) { - app.setScratchDiskPath(scratchPath.fsName, ScratchDiskType.FirstAutoSaveFolder); // see ScratchDiskType object, in ESTK. - } - }, - - getProjectProxySetting: function () { - var returnVal = ""; - if (app.project) { - var returnVal = "No sequence detected in " + app.project.name + "."; - if (app.getEnableProxies()) { - returnVal = 'true'; - } else { - returnVal = 'false'; - } - } else { - returnVal = "No project available."; - } - return returnVal; - }, - - toggleProxyState: function () { - var update = "Proxies for " + app.project.name + " turned "; - if (app.getEnableProxies()) { - app.setEnableProxies(0); - update = update + "OFF."; - app.setSDKEventMessage(update, 'info'); - } else { - app.setEnableProxies(1); - update = update + "ON."; - app.setSDKEventMessage(update, 'info'); - } - }, - - setProxiesON: function () { - var firstProjectItem = app.project.rootItem.children[0]; - if (firstProjectItem) { - if (firstProjectItem.canProxy()) { - var shouldAttachProxy = true; - if (firstProjectItem.hasProxy()) { - shouldAttachProxy = confirm(firstProjectItem.name + " already has an assigned proxy. Re-assign anyway?", false, "Are you sure...?"); - } - if (shouldAttachProxy) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - var proxyPath = File.openDialog("Choose proxy for " + firstProjectItem.name + ":", - filterString, - false); - if (proxyPath.exists) { - firstProjectItem.attachProxy(proxyPath.fsName, 0); - } else { - $._PPP_.updateEventPanel("Could not attach proxy from " + proxyPath + "."); - } - } - } else { - $._PPP_.updateEventPanel("Cannot attach a proxy to " + firstProjectItem.name + "."); - } - } else { - $._PPP_.updateEventPanel("No project item available."); - } - }, - - clearCache: function () { - app.enableQE(); - MediaType = {}; - - // Magical constants from Premiere Pro's internal automation. - - MediaType.VIDEO = "228CDA18-3625-4d2d-951E-348879E4ED93"; - MediaType.AUDIO = "80B8E3D5-6DCA-4195-AEFB-CB5F407AB009"; - MediaType.ANY = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"; - qe.project.deletePreviewFiles(MediaType.ANY); - $._PPP_.updateEventPanel("All video and audio preview files deleted."); - }, - - randomizeSequenceSelection: function () { - var sequence = app.project.activeSequence; - - if (sequence) { - var trackGroups = [sequence.audioTracks, sequence.videoTracks]; - var trackGroupNames = ["audioTracks", "videoTracks"]; - var updateUI = true; - var before; - - for (var gi = 0; gi < 2; gi++) { - $._PPP_.updateEventPanel(trackGroupNames[gi]); - group = trackGroups[gi]; - for (var ti = 0; ti < group.numTracks; ti++) { - var track = group[ti]; - var clips = track.clips; - var transitions = track.transitions; - var beforeSelected; - var afterSelected; - - $._PPP_.updateEventPanel("track : " + ti + " clip count: " + clips.numTracks + " transition count: " + transitions.numTracks); - - for (var ci = 0; ci < clips.numTracks; ci++) { - var clip = clips[ci]; - name = (clip.projectItem === undefined ? "" : clip.projectItem.name); - before = clip.isSelected(); - - // randomly select clips - clip.setSelected((Math.random() > 0.5), updateUI); - - if (clip.isAdjustmentLayer()) { // new in 13.0 - $._PPP_.updateEventPanel("Clip named \"" + clip.name + "\" is an adjustment layer."); - } - - // Note; there's no good place to exercise this code yet, but - // I wanted to provide example usage. - - var allClipsInThisSequenceFromSameSource = clip.getLinkedItems(); - - if (allClipsInThisSequenceFromSameSource) { - $._PPP_.updateEventPanel("Found " + allClipsInThisSequenceFromSameSource.numItems + " clips from " + clip.projectItem.name + ", in this sequence."); - } - beforeSelected = before ? "Y" : "N"; - afterSelected = clip.selected ? "Y" : "N"; - $._PPP_.updateEventPanel("clip : " + ci + " " + name + " " + beforeSelected + " -> " + afterSelected); - } - - for (var tni = 0; tni < transitions.numTracks; ++tni) { - var transition = transitions[tni]; - before = transition.isSelected(); - - // randomly select transitions - transition.setSelected((Math.random() > 0.5), updateUI); - - beforeSelected = before ? "Y" : "N"; - afterSelected = transition.selected ? "Y" : "N"; - - $._PPP_.updateEventPanel('transition: ' + tni + " " + beforeSelected + " -> " + afterSelected); - } - } - } - } else { - $._PPP_.updateEventPanel("no active sequence."); - } - }, - - // Define a couple of callback functions, for AME to use during render. - - onEncoderJobComplete: function (jobID, outputFilePath) { - var eoName; - - if (Folder.fs == 'Macintosh') { - eoName = "PlugPlugExternalObject"; - } else { - eoName = "PlugPlugExternalObject.dll"; - } - - var suffixAddedByPPro = '_1'; // You should really test for any suffix. - var withoutExtension = outputFilePath.slice(0, -4); // trusting 3 char extension - var lastIndex = outputFilePath.lastIndexOf("."); - var extension = outputFilePath.substr(lastIndex + 1); - - if (outputFilePath.indexOf(suffixAddedByPPro)) { - $._PPP_.updateEventPanel(" Output filename was changed: the output preset name may have been added, or there may have been an existing file with that name. This would be a good place to deal with such occurrences."); - } - - var mylib = new ExternalObject('lib:' + eoName); - var eventObj = new CSXSEvent(); - - eventObj.type = "com.adobe.csxs.events.PProPanelRenderEvent"; - eventObj.data = "Rendered Job " + jobID + ", to " + outputFilePath + "."; - - eventObj.dispatch(); - }, - - onEncoderJobError: function (jobID, errorMessage) { - var eoName; - - if (Folder.fs === 'Macintosh') { - eoName = "PlugPlugExternalObject"; - } else { - eoName = "PlugPlugExternalObject.dll"; - } - - var mylib = new ExternalObject('lib:' + eoName); - var eventObj = new CSXSEvent(); - - eventObj.type = "com.adobe.csxs.events.PProPanelRenderEvent"; - eventObj.data = "Job " + jobID + " failed, due to " + errorMessage + "."; - eventObj.dispatch(); - }, - - onEncoderJobProgress: function (jobID, progress) { - $._PPP_.updateEventPanel('onEncoderJobProgress called. jobID = ' + jobID + '. progress = ' + progress + '.'); - }, - - onEncoderJobQueued: function (jobID) { - app.encoder.startBatch(); - }, - - onEncoderJobCanceled: function (jobID) { - $._PPP_.updateEventPanel('OnEncoderJobCanceled called. jobID = ' + jobID + '.'); - }, - - onPlayWithKeyframes: function () { - var seq = app.project.activeSequence; - if (seq) { - var firstVideoTrack = seq.videoTracks[0]; - if (firstVideoTrack) { - var firstClip = firstVideoTrack.clips[0]; - if (firstClip) { - var clipComponents = firstClip.components; - if (clipComponents) { - for (var i = 0; i < clipComponents.numItems; ++i) { - $._PPP_.updateEventPanel('component ' + i + ' = ' + clipComponents[i].matchName + ' : ' + clipComponents[i].displayName); - } - if (clipComponents.numItems > 2) { - - // 0 = clip - // 1 = Opacity - // N effects, then... - // Shape layer (new in 12.0) - - var blur = clipComponents[2]; // Assume Gaussian Blur is the first effect applied to the clip. - if (blur) { - var blurProps = blur.properties; - if (blurProps) { - for (var j = 0; j < blurProps.numItems; ++j) { - $._PPP_.updateEventPanel('param ' + j + ' = ' + blurProps[j].displayName); - } - var blurriness = blurProps[0]; - if (blurriness) { - if (!blurriness.isTimeVarying()) { - blurriness.setTimeVarying(true); - } - for (var k = 0; k < 20; ++k) { - updateUI = (k == 9); // Decide how often to update PPro's UI - blurriness.addKey(k); - var blurVal = Math.sin(3.14159 * i / 5) * 20 + 25; - blurriness.setValueAtKey(k, blurVal, updateUI); - } - } - var repeatEdgePixels = blurProps[2]; - if (repeatEdgePixels) { - if (!repeatEdgePixels.getValue()) { - updateUI = true; - repeatEdgePixels.setValue(true, updateUI); - } - } - // look for keyframe nearest to 4s with 1/10 second tolerance - var keyFrameTime = blurriness.findNearestKey(4.0, 0.1); - if (keyFrameTime !== undefined) { - $._PPP_.updateEventPanel('Found keyframe = ' + keyFrameTime.seconds); - } else { - $._PPP_.updateEventPanel('Keyframe not found.'); - } - - // scan keyframes, forward - - keyFrameTime = blurriness.findNearestKey(0.0, 0.1); - var lastKeyFrameTime = keyFrameTime; - while (keyFrameTime !== undefined) { - $._PPP_.updateEventPanel('keyframe @ ' + keyFrameTime.seconds); - lastKeyFrameTime = keyFrameTime; - keyFrameTime = blurriness.findNextKey(keyFrameTime); - } - - // scan keyframes, backward - keyFrameTime = lastKeyFrameTime; - while (keyFrameTime !== undefined) { - $._PPP_.updateEventPanel('keyframe @ ' + keyFrameTime.seconds); - lastKeyFrameTime = keyFrameTime; - keyFrameTime = blurriness.findPreviousKey(keyFrameTime); - } - - // get all keyframes - - var blurKeyframesArray = blurriness.getKeys(); - if (blurKeyframesArray) { - $._PPP_.updateEventPanel(blurKeyframesArray.length + ' keyframes found'); - } - - // remove keyframe at 19s - blurriness.removeKey(19); - - // remove keyframes in range from 0s to 5s - var shouldUpdateUI = true; - blurriness.removeKeyRange(0, 5, shouldUpdateUI); - } - - } else { - $._PPP_.updateEventPanel("Please apply the Gaussian Blur effect to the first clip in the first video track of the active sequence."); - } - } - } - } - } - } else { - $._PPP_.updateEventPanel("no active sequence."); - } - }, - - extractFileNameFromPath: function (fullPath) { - var lastDot = fullPath.lastIndexOf("."); - var lastSep = fullPath.lastIndexOf("/"); - - if (lastDot > -1) { - return fullPath.substr((lastSep + 1), (fullPath.length - (lastDot + 1))); - } else { - return fullPath; - } - }, - - onProxyTranscodeJobComplete: function (jobID, outputFilePath) { - var suffixAddedByPPro = '_1'; // You should really test for any suffix. - var withoutExtension = outputFilePath.slice(0, -4); // trusting 3 char extension - var lastIndex = outputFilePath.lastIndexOf("."); - var extension = outputFilePath.substr(lastIndex + 1); - - var wrapper = []; - wrapper[0] = outputFilePath; - - var nameToFind = 'Proxies generated by PProPanel'; - var targetBin = $._PPP_.getPPPInsertionBin(); - if (targetBin) { - app.project.importFiles(wrapper); - } - }, - - onProxyTranscodeJobError: function (jobID, errorMessage) { - $._PPP_.updateEventPanel(errorMessage); - }, - - onProxyTranscodeJobQueued: function (jobID) { - app.encoder.startBatch(); - }, - - ingestFiles: function (outputPresetPath) { - app.encoder.bind('onEncoderJobComplete', $._PPP_.onProxyTranscodeJobComplete); - app.encoder.bind('onEncoderJobError', $._PPP_.onProxyTranscodeJobError); - app.encoder.bind('onEncoderJobQueued', $._PPP_.onProxyTranscodeJobQueued); - app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); - - if (app.project) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - var fileOrFilesToImport = File.openDialog("Choose full resolution files to import", // title - filterString, // filter available files? - true); // allow multiple? - if (fileOrFilesToImport) { - var nameToFind = 'Proxies generated by PProPanel'; - var targetBin = $._PPP_.searchForBinWithName(nameToFind); - if (targetBin === 0) { - // If panel can't find the target bin, it creates it. - app.project.rootItem.createBin(nameToFind); - targetBin = $._PPP_.searchForBinWithName(nameToFind); - } - if (targetBin) { - targetBin.select(); - var importThese = []; // We have an array of File objects; importFiles() takes an array of paths. - if (importThese) { - for (var i = 0; i < fileOrFilesToImport.length; i++) { - importThese[i] = fileOrFilesToImport[i].fsName; - var justFileName = extractFileNameFromPath(importThese[i]); - var suffix = '_PROXY.mp4'; - var containingPath = fileOrFilesToImport[i].parent.fsName; - var completeProxyPath = containingPath + $._PPP_.getSep() + justFileName + suffix; - - var jobID = app.encoder.encodeFile(fileOrFilesToImport[i].fsName, - completeProxyPath, - outputPresetPath, - 0); - } - - app.project.importFiles(importThese, - 1, // suppress warnings - targetBin, - 0); // import as numbered stills - } - } else { - $._PPP_.updateEventPanel("Could not find or create target bin."); - } - } else { - $._PPP_.updateEventPanel("No files to import."); - } - } else { - $._PPP_.updateEventPanel("No project found."); - } - }, - - insertOrAppend: function () { - var seq = app.project.activeSequence; - if (seq) { - var first = app.project.rootItem.children[0]; - if (first) { - var numVTracks = seq.videoTracks.numTracks; - var targetVTrack = seq.videoTracks[(numVTracks - 1)]; - if (targetVTrack) { - // If there are already clips in this track, - // append this one to the end. Otherwise, - // insert at start time. - - if (targetVTrack.clips.numItems > 0) { - var lastClip = targetVTrack.clips[(targetVTrack.clips.numItems - 1)]; - if (lastClip) { - targetVTrack.insertClip(first, lastClip.end.seconds); - } - } else { - targetVTrack.insertClip(first, '00;00;00;00'); - } - } else { - $._PPP_.updateEventPanel("Could not find first video track."); - } - } else { - $._PPP_.updateEventPanel("Couldn't locate first projectItem."); - } - } else { - $._PPP_.updateEventPanel("no active sequence."); - } - }, - - overWrite: function () { - var seq = app.project.activeSequence; - if (seq) { - var first = app.project.rootItem.children[0]; - if (first) { - var vTrack1 = seq.videoTracks[0]; - if (vTrack1) { - var now = seq.getPlayerPosition(); - vTrack1.overwriteClip(first, now.seconds); - } else { - $._PPP_.updateEventPanel("Could not find first video track."); - } - } else { - $._PPP_.updateEventPanel("Couldn't locate first projectItem."); - } - } else { - $._PPP_.updateEventPanel("no active sequence."); - } - }, - - closeFrontSourceClip: function () { - app.sourceMonitor.closeClip(); - }, - - closeAllClipsInSourceMonitor: function () { - app.sourceMonitor.closeAllClips(); - }, - - changeLabel: function () { - var first = app.project.rootItem.children[0]; - if (first) { - var currentLabel = first.getColorLabel(); - var newLabel = currentLabel + 1; // 4 = Cerulean. 0 = Violet, 15 = Yellow. - if (newLabel > 15) { - newLabel = newLabel - 16; - } - app.setSDKEventMessage("Previous Label color = " + currentLabel + ".", 'info'); - first.setColorLabel(newLabel); - app.setSDKEventMessage("New Label color = " + newLabel + ".", 'info'); - } else { - $._PPP_.updateEventPanel("Couldn't locate first projectItem."); - } - }, - - getPPPInsertionBin: function () { - var nameToFind = "Here's where PProPanel puts things."; - - var targetBin = $._PPP_.searchForBinWithName(nameToFind); - - if (targetBin === undefined) { - // If panel can't find the target bin, it creates it. - app.project.rootItem.createBin(nameToFind); - targetBin = $._PPP_.searchForBinWithName(nameToFind); - } - if (targetBin) { - targetBin.select(); - return targetBin; - } - }, - - importComps: function () { - var targetBin = $._PPP_.getPPPInsertionBin(); - if (targetBin) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "All files:*.*"; - } - compNamesToImport = []; - - var aepToImport = File.openDialog("Choose After Effects project", // title - filterString, // filter available files? - false); // allow multiple? - if (aepToImport) { - var importAll = confirm("Import all compositions in project?", false, "Import all?"); - if (importAll) { - var result = app.project.importAllAEComps(aepToImport.fsName, targetBin); - } else { - var compName = prompt('Name of composition to import?', - '', - 'Which Comp to import'); - if (compName) { - compNamesToImport[0] = compName; - var importAECompResult = app.project.importAEComps(aepToImport.fsName, compNamesToImport, targetBin); - } else { - $._PPP_.updateEventPanel("Could not find Composition."); - } - } - } else { - $._PPP_.updateEventPanel("Could not open project."); - } - } else { - $._PPP_.updateEventPanel("Could not find or create target bin."); - } - }, - - consolidateProject: function () { - var pmo = app.projectManager.options; - - if (app.project.sequences.length) { - if (pmo) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "Output Presets:*.epr"; - } - - var outFolder = Folder.selectDialog("Choose output directory."); - if (outFolder) { - - var presetPath = ""; - var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); - if (useSpecificPreset) { - var useThisEPR = File.openDialog("Choose output preset (.epr file)", // title - filterString, // filter available files? - false); // allow multiple? - - if (useThisEPR) { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; - pmo.encoderPresetFilePath = useThisEPR.fsName; - } - } else { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; - } - - var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); - - if (processAllSequences) { - pmo.includeAllSequences = true; - } else { - pmo.includeAllSequences = false; - pmo.affectedSequences = [app.project.sequences[0]]; - } - - pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; - pmo.convertAECompsToClips = false; - pmo.convertSyntheticsToClips = false; - pmo.copyToPreventAlphaLoss = false; - pmo.destinationPath = outFolder.fsName; - pmo.excludeUnused = false; - pmo.handleFrameCount = 0; - pmo.includeConformedAudio = true; - pmo.includePreviews = true; - pmo.renameMedia = false; - - var result = app.projectManager.process(app.project); - var errorList = app.projectManager.errors; - - if (errorList.length) { - for (var k = 0; k < errorList.length; k++) { - $._PPP_.updateEventPanel(errorList[k][1]); - } - } else { - $._PPP_.updateEventPanel(app.project.name + " successfully processed to " + outFolder.fsName + "."); - } - return result; - } - } - - - } - if (pmo) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "Output Presets:*.epr"; - } - - var outFolder = Folder.selectDialog("Choose output directory."); - if (outFolder) { - - var presetPath = ""; - var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); - if (useSpecificPreset) { - var useThisEPR = File.openDialog("Choose output preset (.epr file)", // title - filterString, // filter available files? - false); // allow multiple? - - if (useThisEPR) { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; - pmo.encoderPresetFilePath = useThisEPR.fsName; - } - } else { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; - } - - var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); - - if (processAllSequences) { - pmo.includeAllSequences = true; - } else { - pmo.includeAllSequences = false; - pmo.affectedSequences = [app.project.sequences[0]]; - } - - pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; - pmo.convertAECompsToClips = false; - pmo.convertSyntheticsToClips = false; - pmo.copyToPreventAlphaLoss = false; - pmo.destinationPath = outFolder.fsName; - pmo.excludeUnused = false; - pmo.handleFrameCount = 0; - pmo.includeConformedAudio = true; - pmo.includePreviews = true; - pmo.renameMedia = false; - - var result = app.projectManager.process(app.project); - var errorList = app.projectManager.errors; - - if (errorList.length) { - for (var k = 0; k < errorList.length; k++) { - $._PPP_.updateEventPanel(errorList[k][1]); - } - } else { - $._PPP_.updateEventPanel(app.project.name + " successfully processed to " + outFolder.fsName + "."); - } - return result; - } - } - }, - - importMoGRT: function () { - var activeSeq = app.project.activeSequence; - if (activeSeq) { - var filterString = ""; - if (Folder.fs === 'Windows') { - filterString = "Motion Graphics Templates:*.mogrt"; - } - var mogrtToImport = File.openDialog("Choose MoGRT", // title - filterString, // filter available files? - false); // allow multiple? - if (mogrtToImport) { - var targetTime = activeSeq.getPlayerPosition(); - var vidTrackOffset = 0; - var audTrackOffset = 0; - var newTrackItem = activeSeq.importMGT(mogrtToImport.fsName, - targetTime.ticks, - vidTrackOffset, - audTrackOffset); - if (newTrackItem) { - var moComp = newTrackItem.getMGTComponent(); - if (moComp) { - var params = moComp.properties; - for (var z = 0; z < params.numItems; z++) { - var thisParam = params[0]; - } - var srcTextParam = params.getParamForDisplayName("Main Title"); - if (srcTextParam) { - var val = srcTextParam.getValue(); - srcTextParam.setValue("New value set by PProPanel!"); - } - } - } - } else { - app.setSDKEventMessage('Unable to import ' + mogrtToImport.fsName + '.', 'error'); - } - } else { - app.setSDKEventMessage('No active sequence.'); - } - }, - - reportCurrentProjectSelection: function () { - var viewIDs = app.getProjectViewIDs(); // sample code optimized for a single open project - viewSelection = app.getProjectViewSelection(viewIDs[0]); - $._PPP_.projectPanelSelectionChanged(viewSelection, viewIDs[0]); - }, - - randomizeProjectSelection: function () { - var viewIDs = app.getProjectViewIDs(); - var firstProject = app.getProjectFromViewID(viewIDs[0]); - var arrayOfRandomProjectItems = []; - - for (var b = 0; b < app.project.rootItem.children.numItems; b++) { - var currentProjectItem = app.project.rootItem.children[b]; - if (Math.random() > 0.5) { - arrayOfRandomProjectItems.push(currentProjectItem); - } - } - if (arrayOfRandomProjectItems.length > 0) { - app.setProjectViewSelection(arrayOfRandomProjectItems, viewIDs[0]); - } - }, - - setAllProjectItemsOnline: function (startingBin) { - for (var k = 0; k < startingBin.children.numItems; k++) { - var currentChild = startingBin.children[k]; - if (currentChild) { - if (currentChild.type === ProjectItemType.BIN) { - $._PPP_.setAllProjectItemsOnline(currentChild); // warning; recursion! - } else if (currentChild.isOffline()) { - currentChild.changeMediaPath(currentChild.getMediaPath(), true); - if (currentChild.isOffline()) { - $._PPP_.updateEventPanel("Failed to bring \'" + currentChild.name + "\' online."); - } else { - $._PPP_.updateEventPanel("\'" + currentChild.name + "\' is once again online."); - } - } - } - } - }, - - setAllOnline: function () { - var startingBin = app.project.rootItem; - $._PPP_.setAllProjectItemsOnline(startingBin); - }, - - setOffline: function () { - var viewIDs = app.getProjectViewIDs(); - for (var a = 0; a < app.projects.numProjects; a++) { - var currentProject = app.getProjectFromViewID(viewIDs[a]); - if (currentProject) { - if (currentProject.documentID === app.project.documentID) { // We're in the right project! - var selectedItems = app.getProjectViewSelection(viewIDs[a]); - for (var b = 0; b < selectedItems.length; b++) { - var currentItem = selectedItems[b]; - if (currentItem) { - if ((!currentItem.isSequence()) && (currentItem.type !== ProjectItemType.BIN)) { // For every selected item which isn't a bin or sequence... - if (currentItem.isOffline()) { - $._PPP_.updateEventPanel("\'" + currentItem.name + "\'was already offline."); - } else { - var result = currentItem.setOffline(); - $._PPP_.updateEventPanel("\'" + currentItem.name + "\' is now offline."); - } - } - } - } - } - } - } - }, - - updateFrameRate: function () { - var item = app.project.rootItem.children[0]; - if (item) { - if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)) { - // If there is an item, and it's either a clip or file... - item.setOverrideFrameRate(23.976); - } else { - $._PPP_.updateEventPanel('You cannot override the frame rate of bins or sequences.'); - } - } else { - $._PPP_.updateEventPanel("No project items found."); - } - }, - - onItemAddedToProject: function (whichProject, addedProjectItem) { - var msg = addedProjectItem.name + " was added to " + whichProject + "." - $._PPP_.updateEventPanel(msg); - }, - - registerItemAddedFxn: function () { - app.onItemAddedToProjectSuccess = $._PPP_.onItemAddedToProject; - }, - - myOnProjectChanged: function (documentID) { - var msg = 'Project with ID ' + documentID + ' Changed.'; - // Commented out, as this happens a LOT. - // $._PPP_.updateEventPanel(msg); - }, - - registerProjectChangedFxn: function () { - app.bind('onProjectChanged', $._PPP_.myOnProjectChanged); - }, - - confirmPProHostVersion: function () { - var version = parseFloat(app.version); - if (version < 12.1) { - $._PPP_.updateEventPanel("Note: PProPanel relies on features added in 12.1, but is currently running in " + version + "."); - } - }, - - changeMarkerColors: function () { - if (app.project.rootItem.children.numItems > 0) { - var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. - if (projectItem) { - if (projectItem.type == ProjectItemType.CLIP || - projectItem.type == ProjectItemType.FILE) { - - markers = projectItem.getMarkers(); - - if (markers) { - var markerCount = markers.numMarkers; - - if (markerCount) { - for (var thisMarker = markers.getFirstMarker(); thisMarker !== undefined; thisMarker = markers.getNextMarker(thisMarker)) { - var oldColor = thisMarker.getColorByIndex(); - var newColor = oldColor + 1; - if (newColor > 7) { - newColor = 0; - } - thisMarker.setColorByIndex(newColor); - $._PPP_.updateEventPanel("Changed color of marker named \'" + thisMarker.name + "\' from " + oldColor + " to " + newColor + "."); - } - } - } - } else { - $._PPP_.updateEventPanel("Can only add markers to footage items."); - } - } else { - $._PPP_.updateEventPanel("Could not find first projectItem."); - } - } else { - $._PPP_.updateEventPanel("Project is empty."); - } - }, - - changeSeqTimeCodeDisplay: function () { - if (app.project.activeSequence) { - var currentSeqSettings = app.project.activeSequence.getSettings(); - if (currentSeqSettings) { - var oldVidSetting = currentSeqSettings.videoDisplayFormat; - currentSeqSettings.videoDisplayFormat = oldVidSetting + 1; - if (currentSeqSettings.videoDisplayFormat > TIMEDISPLAY_48Timecode) { - currentSeqSettings.videoDisplayFormat = TIMEDISPLAY_24Timecode; - } - app.project.activeSequence.setSettings(currentSeqSettings); - $._PPP_.updateEventPanel("Changed timecode display format for \'" + app.project.activeSequence.name + "\'."); - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - myActiveSequenceChangedFxn: function () { - $._PPP_.updateEventPanel("Active sequence is now " + app.project.activeSequence.name + "."); - }, - - myActiveSequenceSelectionChangedFxn: function () { - var sel = app.project.activeSequence.getSelection(); - $._PPP_.updateEventPanel('Current active sequence = ' + app.project.activeSequence.name + '.'); - $._PPP_.updateEventPanel(sel.length + ' track items selected.'); - for (var i = 0; i < sel.length; i++) { - if (sel[i].name !== 'anonymous') { - $._PPP_.updateEventPanel('Selected item ' + (i + 1) + ' == ' + sel[i].name + '.'); - } - } - }, - - registerActiveSequenceChangedFxn: function () { - var success = app.bind("onActiveSequenceChanged", $._PPP_.myActiveSequenceChangedFxn); - }, - - registerSequenceSelectionChangedFxn: function () { - var success = app.bind('onActiveSequenceSelectionChanged', $._PPP_.myActiveSequenceSelectionChangedFxn); - }, - - enableNewWorldScripting: function () { - app.enableQE(); - - var previousNWValue = qe.getDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld"); - var previousInternalDOMValue = qe.getDebugDatabaseEntry("dvascripting.EnabledInternalDOM"); - if ((previousNWValue === 'true') && (previousInternalDOMValue === 'true')) { - qe.setDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld", "false"); - qe.setDebugDatabaseEntry("dvascripting.EnabledInternalDOM", "false"); - $._PPP_.updateEventPanel("ScriptLayerPPro.EnableNewWorld and dvascripting.EnabledInternalDOM are now OFF."); - } else { - qe.setDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld", "true"); - qe.setDebugDatabaseEntry("dvascripting.EnabledInternalDOM", "true"); - $._PPP_.updateEventPanel("ScriptLayerPPro.EnableNewWorld and dvascripting.EnabledInternalDOM are now ON."); - } - }, - - insertOrAppendToTopTracks: function () { - var seq = app.project.activeSequence; - if (seq) { - var first = app.project.rootItem.children[0]; - if (first) { - var time = seq.getPlayerPosition(); - var newClip = seq.insertClip(first, time, (seq.videoTracks.numTracks - 1), (seq.audioTracks.numTracks - 1)); - if (newClip) { - $._PPP_.updateEventPanel("Inserted " + newClip.name + ", into " + seq.name + "."); - } - } else { - $._PPP_.updateEventPanel("Couldn't locate first projectItem."); - } - } else { - $._PPP_.updateEventPanel("no active sequence."); - } - }, - - closeAllProjectsOtherThanActiveProject: function () { - var viewIDs = app.getProjectViewIDs(); - var closeTheseProjects = []; - for (var a = 0; a < viewIDs.length; a++) { - var thisProj = app.getProjectFromViewID(viewIDs[a]); - if (thisProj.documentID !== app.project.documentID) { - closeTheseProjects[a] = thisProj; - } - } - // Why do this afterward? Because if we close projects in that loop, we change the active project. :) - for (var b = 0; b < closeTheseProjects.length; b++) { - $._PPP_.updateEventPanel("Closed " + closeTheseProjects[b].name); - closeTheseProjects[b].closeDocument(); - } - }, - - countAdjustmentLayersInBin: function (parentItem, arrayOfAdjustmentLayerNames, foundSoFar) { - for (var j = 0; j < parentItem.children.numItems; j++) { - var currentChild = parentItem.children[j]; - if (currentChild) { - if (currentChild.type == ProjectItemType.BIN) { - $._PPP_.countAdjustmentLayersInBin(currentChild, arrayOfAdjustmentLayerNames, foundSoFar); // warning; recursion! - } else { - if (currentChild.isAdjustmentLayer()) { - arrayOfAdjustmentLayerNames[foundSoFar] = currentChild.name; - foundSoFar++; - } - } - } - } - }, - - findAllAdjustmentLayersInProject: function () { - var arrayOfAdjustmentLayerNames = []; - var foundSoFar = 0; - var startingBin = app.project.rootItem; - - $._PPP_.countAdjustmentLayersInBin(startingBin, arrayOfAdjustmentLayerNames, foundSoFar); - if (arrayOfAdjustmentLayerNames.length) { - var remainingArgs = arrayOfAdjustmentLayerNames.length; - var message = remainingArgs + " adjustment layers found: "; - - for (var i = 0; i < arrayOfAdjustmentLayerNames.length; i++) { - message += arrayOfAdjustmentLayerNames[i]; - remainingArgs--; - if (remainingArgs > 1) { - message += ', '; - } - if (remainingArgs === 1) { - message += ", and "; - } - if (remainingArgs === 0) { - message += "."; - } - } - $._PPP_.updateEventPanel(message); - } else { - $._PPP_.updateEventPanel("No adjustment layers found in " + app.project.name + "."); - } - }, - - consolidateDuplicates: function () { - result = app.project.consolidateDuplicates(); - $._PPP_.updateEventPanel("Duplicates consolidated in " + app.project.name + "."); - }, - - closeAllSequences: function () { - var seqList = app.project.sequences; - for (var a = 0; a < seqList.numSequences; a++) { - var currentSeq = seqList[a]; - if (currentSeq) { - currentSeq.close(); - } else { - $._PPP_.updateEventPanel("No sequences from " + app.project.name + " were open."); - } - } - }, - - dumpAllPresets: function () { - var desktopPath = new File("~/Desktop"); - var outputFileName = desktopPath.fsName + $._PPP_.getSep() + 'available_presets.txt'; - var selectedPreset = undefined; - var selectedExporter = undefined; - var exporters = app.encoder.getExporters(); - - var outFile = new File(outputFileName); - - outFile.encoding = "UTF8"; - outFile.open("w", "TEXT", "????"); - - for (var i = 0; i < exporters.length; i++) { - var exporter = exporters[i]; - if (exporter) { - outFile.writeln('-----------------------------------------------'); - outFile.writeln(i + ':' + exporter.name + ' : ' + exporter.classID + ' : ' + exporter.fileType); - var presets = exporter.getPresets(); - if (presets) { - outFile.writeln(presets.length + ' presets found'); - for (var j = 0; j < presets.length; j++) { - var preset = presets[j]; - if (preset) { - outFile.writeln('matchName: ' + preset.matchName + '(' + preset.name + ')'); - if (preset.name.indexOf('TQM') > -1) { - selectedPreset = preset; - selectedExporter = exporter; - outFile.writeln('selected preset = ' + selectedExporter.name + ' : ' + selectedPreset.name); - selectedPreset.writeToFile(desktopPath.fsName + $._PPP_.getSep() + preset.name + ".epr"); - $._PPP_.updateEventPanel("List of available presets saved to desktop as \'available_presets.txt\'"); - } - } - } - } - } - } - desktopPath.close(); - outFile.close(); - }, - - reportSequenceVRSettings: function () { - var seq = app.project.activeSequence; - if (seq) { - var settings = seq.getSettings(); - if (settings) { - $._PPP_.updateEventPanel("===================================================="); - $._PPP_.updateEventPanel("VR Settings for \'" + seq.name + "\':"); - $._PPP_.updateEventPanel(""); - $._PPP_.updateEventPanel(" Horizontal captured view: " + settings.vrHorzCapturedView); - $._PPP_.updateEventPanel(" Vertical captured view: " + settings.vrVertCapturedView); - $._PPP_.updateEventPanel(" Layout: " + settings.Layout); - $._PPP_.updateEventPanel(" Projection: " + settings.vrProjection); - $._PPP_.updateEventPanel(""); - $._PPP_.updateEventPanel("===================================================="); - } - } - }, - - openProjectItemInSource: function () { - var viewIDs = app.getProjectViewIDs(); - if (viewIDs) { - for (var a = 0; a < app.projects.numProjects; a++) { - var currentProject = app.getProjectFromViewID(viewIDs[a]); - if (currentProject) { - if (currentProject.documentID === app.project.documentID) { // We're in the right project! - var selectedItems = app.getProjectViewSelection(viewIDs[a]); - for (var b = 0; b < selectedItems.length; b++) { - var currentItem = selectedItems[b]; - if (currentItem) { - if (currentItem.type !== ProjectItemType.BIN) { // For every selected item which isn't a bin or sequence... - app.sourceMonitor.openProjectItem(currentItem); - } - } else { - $._PPP_.updateEventPanel("No item available."); - } - } - } - } else { - $._PPP_.updateEventPanel("No project available."); - } - } - } else { - $._PPP_.updateEventPanel("No view IDs available."); - } - }, - - reinterpretFootage: function () { - var viewIDs = app.getProjectViewIDs(); - if (viewIDs) { - for (var a = 0; a < app.projects.numProjects; a++) { - var currentProject = app.getProjectFromViewID(viewIDs[a]); - if (currentProject) { - if (currentProject.documentID === app.project.documentID) { // We're in the right project! - var selectedItems = app.getProjectViewSelection(viewIDs[a]); - if (selectedItems) { - for (var b = 0; b < selectedItems.length; b++) { - var currentItem = selectedItems[b]; - if (currentItem) { - if ((currentItem.type !== ProjectItemType.BIN) && - (currentItem.isSequence() === false)) { - var interp = currentItem.getFootageInterpretation(); - if (interp) { - // Note: I made this something terrible, so the change is apparent. - interp.frameRate = 17.868; - interp.pixelAspectRatio = 1.2121; - currentItem.setFootageInterpretation(interp); - } else { - $._PPP_.updateEventPanel("Unable to get interpretation for " + currentItem.name + "."); - } - var mapping = currentItem.getAudioChannelMapping; - if (mapping) { - mapping.audioChannelsType = AUDIOCHANNELTYPE_Stereo; - mapping.audioClipsNumber = 1; - mapping.setMappingForChannel(0, 4); // 1st param = channel index, 2nd param = source index - mapping.setMappingForChannel(1, 5); - currentItem.setAudioChannelMapping(mapping); // submit changed mapping object - } - } - } else { - $._PPP_.updateEventPanel("No project item available."); - } - } - } else { - $._PPP_.updateEventPanel("No items selected."); - } - } - } else { - $._PPP_.updateEventPanel("No project available."); - } - } - } else { - $._PPP_.updateEventPanel("No view IDs available."); - } - }, - - createSubSequence: function () { - - /* Behavioral Note - - createSubSequence() uses track targeting to select clips when there is - no current clip selection, in the sequence. To create a subsequence with - clips on tracks that are currently NOT targeted, either select some clips - (on any track), or temporarily target all desired tracks. - - */ - - var activeSequence = app.project.activeSequence; - if (activeSequence) { - var foundTarget = false; - for (var a = 0; - (a < activeSequence.videoTracks.numTracks) && (foundTarget === false); a++) { - var vTrack = activeSequence.videoTracks[a]; - if (vTrack) { - if (vTrack.isTargeted()) { - foundTarget = true; - } - } - } - // If no targeted track was found, just target the zero-th track, for demo purposes - if (foundTarget === false) { - activeSequence.videotracks[0].setTargeted(true, true); - } - - var cloneAnyway = true; - if ((activeSequence.getInPoint() == NOT_SET) && (activeSequence.getOutPoint() == NOT_SET)) { - cloneAnyway = confirm("No in or out points set; clone entire sequence?", false, "Clone the whole thing?"); - } - if (cloneAnyway) { - var ignoreMapping = confirm("Ignore track mapping?", false, "Ignore track mapping?"); - var newSeq = activeSequence.createSubsequence(ignoreMapping); - // rename newSeq here, as desired. - } - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - selectAllRetimedClips: function () { - var activeSeq = app.project.activeSequence; - var numRetimedClips = 0; - if (activeSeq) { - var trackGroups = [activeSeq.audioTracks, activeSeq.videoTracks]; - var trackGroupNames = ["audioTracks", "videoTracks"]; - var updateUI = true; - - for (var gi = 0; gi < 2; gi++) { - group = trackGroups[gi]; - for (var ti = 0; ti < group.numTracks; ti++) { - var track = group[ti]; - var clips = track.clips; - for (var ci = 0; ci < clips.numTracks; ci++) { - var clip = clips[ci]; - if (clip.getSpeed() !== 1) { - clip.setSelected(true, updateUI); - numRetimedClips++; - } - } - } - } - $._PPP_.updateEventPanel(numRetimedClips + " retimed clips found."); - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - selectReversedClips: function () { - var sequence = app.project.activeSequence; - var numReversedClips = 0; - if (sequence) { - var trackGroups = [sequence.audioTracks, sequence.videoTracks]; - var trackGroupNames = ["audioTracks", "videoTracks"]; - var updateUI = true; - - for (var gi = 0; gi < 2; gi++) { - for (var ti = 0; ti < group.numTracks; ti++) { - for (var ci = 0; ci < group[ti].clips.numTracks; ci++) { - var clip = group[ti].clips[ci]; - var isReversed = clip.isSpeedReversed(); - if (isReversed) { - clip.setSelected(isReversed, updateUI); - numReversedClips++; - } - } - } - } - $._PPP_.updateEventPanel(numReversedClips + " reversed clips found."); - } else { - $._PPP_.updateEventPanel("No active sequence."); - } - }, - - logConsoleOutput: function () { - app.enableQE(); - var logFileName = "PPro_Console_output.txt" - var outFolder = Folder.selectDialog("Where do you want to save the log file?"); - if (outFolder) { - var entireOutputPath = outFolder.fsName + $._PPP_.getSep() + logFileName; - var result = qe.executeConsoleCommand("con.openlog " + entireOutputPath); - $._PPP_.updateEventPanel("Log opened at " + entireOutputPath + "."); - } - }, - - closeLog: function () { - app.enableQE(); - qe.executeConsoleCommand("con.closelog"); - }, - - stitch: function (presetPath) { - var viewIDs = app.getProjectViewIDs(); - var allPathsToStitch = ""; - - for (var a = 0; a < app.projects.numProjects; a++) { - var currentProject = app.getProjectFromViewID(viewIDs[a]); - if (currentProject) { - if (currentProject.documentID === app.project.documentID) { // We're in the right project! - var selectedItems = app.getProjectViewSelection(viewIDs[a]); - if (selectedItems.length) { - for (var b = 0; b < selectedItems.length; b++) { - var currentItem = selectedItems[b]; - if (currentItem) { - if ((!currentItem.isSequence()) && (currentItem.type !== ProjectItemType.BIN)) { // For every selected item which isn't a bin or sequence... - allPathsToStitch += currentItem.getMediaPath(); - allPathsToStitch += ";"; - } - } - } - - var AMEString = "var fe = app.getFrontend(); fe.stitchFiles(\"" + allPathsToStitch + "\""; - var addendum = ", \"H.264\", \"" + presetPath + "\", " + "\"(This path parameter is never used)\");"; - - AMEString += addendum; - - // 3. Send Command to AME for Export // - var bt = new BridgeTalk(); - bt.target = 'ame'; - bt.body = AMEString; - bt.send(); - - - - } - } - } - } - }, - - clearESTKConsole: function () { - var bt = new BridgeTalk(); - bt.target = 'estoolkit-4.0'; - bt.body = function () { - app.clc(); - }.toSource() + "()"; - bt.send(); - } -}; diff --git a/pype/hosts/premiere/extensions/com.pype.rename/jsx/PypeRename.jsx b/pype/hosts/premiere/extensions/com.pype.rename/jsx/PypeRename.jsx deleted file mode 100644 index ac405761b6..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/jsx/PypeRename.jsx +++ /dev/null @@ -1,359 +0,0 @@ -/* global app, XMPMeta, ExternalObject, CSXSEvent, Folder */ -/* -------------------------------------- - -. == [ part 0f PyPE CluB ] == .- -_______________.___._____________________ -\______ \__ | |\______ \_ _____/ - | ___// | | | ___/| __)_ - | | \____ | | | | \ - |____| / ______| |____| /_______ / - \/ \/ - .. __/ CliP R3N4M3R \__ .. -*/ -var renamer = {}; - -/** - * Sequence-rename selected clips and establish their hierarchy based upon provided - * data. Using data.folder, data.episode, data.sequence to name a clip and write - * resulting hierarchical clip data into sequence metadata via XMP. - * - * @param {Object} data - data {'folder', 'episode', 'sequence', 'pattern', 'increment', 'start'} - * @return {String} state - */ -renamer.renameSeqHierarchy = function (data) { // eslint-disable-line no-unused-vars - var sequence = app.project.activeSequence; - var selected = sequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - app.setSDKEventMessage('pattern ' + data.pattern + '\n' + 'increment ' + data.increment, 'info'); - // get padding - var padPtr = RegExp('(?:.*?)(#+)(.*)'); - var res = data.pattern.match(padPtr); - // res is now null if there is no padding string (###) in Pattern - // res[1] is padding string - if (!res) { - app.setSDKEventMessage('no padding string detected in pattern ' + data.pattern, 'error'); - return false; - } - - // convert to int - var index = parseInt(data.start); - // change padding string to zero: '####' -> '0000' - var rx = RegExp('#', 'g'); - var fgexp = RegExp('{folder}', 'i'); - var egexp = RegExp('{episode}', 'i'); - var sgexp = RegExp('{sequence}', 'i'); - var shotrg = RegExp('{shot}', 'i'); - var zero = res[1].replace(rx, '0'); - // iterate over selection - var metadata = renamer.getSequencePypeMetadata(sequence); - for (var c = 0; c < selected.length; c++) { - var mediaType = selected[c].mediaType; - if (mediaType === 'Audio') { - continue - } - delete metadata.clips[selected[c].name]; - // convert index to string - var indexStr = '' + index; - // left-zero pad number - var padding = zero.substring(0, zero.length - indexStr.length) + indexStr; - // put name together - // replace {shot} token - selected[c].name = data.pattern.replace(shotrg, selected[c].name); - selected[c].name = selected[c].name.replace(res[1], padding); - selected[c].name = selected[c].name.replace(fgexp, data.folder); - selected[c].name = selected[c].name.replace(egexp, data.episode); - selected[c].name = selected[c].name.replace(sgexp, data.sequence); - - // fill in hierarchy if set - var parents = []; - var hierarchy = []; - - if (data.folder) { - parents.push({ - 'entityType': 'folder', - 'entityName': data.folder - }); - hierarchy.push(data.folder); - } - - if (data.episode) { - parents.push({ - 'entityType': 'episode', - 'entityName': data.episode - }); - hierarchy.push(data.episode); - } - - if (data.sequence) { - parents.push({ - 'entityType': 'sequence', - 'entityName': data.sequence - }); - hierarchy.push(data.sequence); - } - - // push it to metadata - metadata.clips[selected[c].name] = { - 'parents': parents, - 'hierarchy': hierarchy.join('/'), - }; - - // add increment - index = index + parseInt(data.increment); - } - - renamer.setSequencePypeMetadata(sequence, metadata); - - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); - -}; - -/** - * Sequence rename seleced clips - * @param {Object} data - {pattern, start, increment} - */ -renamer.renameSeq = function (data) { // eslint-disable-line no-unused-vars - var selected = app.project.activeSequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - app.setSDKEventMessage('pattern ' + data.pattern + '\n' + 'increment ' + data.increment, 'info'); - // get padding - var padPtr = RegExp('(?:.*?)(#+)(?:.*)'); - var res = data.pattern.match(padPtr); - // res is now null if there is no padding string (###) in Pattern - // res[1] is padding string - - if (!res) { - app.setSDKEventMessage('no padding string detected in pattern ' + data.pattern, 'error'); - return false; - } - - // convert to int - var index = parseInt(data.start); - // change padding string to zero: '####' -> '0000' - var rx = RegExp('#', 'g'); - var zero = res[2].replace(rx, '0'); - // iterate over selection - for (var c = 0; c < selected.length; c++) { - // convert index to string - var indexStr = '' + index; - // left-zero pad number - var padding = zero.substring(0, zero.length - indexStr.length) + indexStr; - // put name together - selected[c].name = data.pattern.replace(res[1], padding); - // add increment - index = index + parseInt(data.increment); - } - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); -}; - -/** - * Simple rename clips - * @param {string} newName - new clip name. `{shot}` designates current clip name - * @return {string} result - return stringified JSON status - */ -renamer.renameSimple = function (newName) { // eslint-disable-line no-unused-vars - app.setSDKEventMessage('Replacing with pattern ' + newName, 'info'); - var selected = app.project.activeSequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - var rx = RegExp('{shot}', 'i'); - for (var c = 0; c < selected.length; c++) { - // find {shot} token and replace it with existing clip name - selected[c].name = newName.replace(rx, selected[c].name); - } - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); -}; - -/** - * Find string in clip name and replace it with another - * @param {Object} data - {find, replaceWith} object - * @return {string} result - return stringified JSON status - */ -renamer.renameFindReplace = function (data) { // eslint-disable-line no-unused-vars - var selected = app.project.activeSequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - - var rx = RegExp('{shot}', 'i'); - for (var c = 0; c < selected.length; c++) { - // replace {shot} token with actual clip name - var find = data.find.replace(rx, selected[c].name); - var repl = data.replaceWith.replace(rx, selected[c].name); - // replace find with replaceWith - selected[c].name = selected[c].name.replace(find, repl); - } - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); -}; - -/** - * Replace current clip name with filename (without extension) - * @return {string} result - return stringified JSON status - */ -renamer.renameClipRename = function () { // eslint-disable-line no-unused-vars - var selected = app.project.activeSequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - - var regexp = new RegExp('.[^/.]+$'); - for (var c = 0; c < selected.length; c++) { - // suddenly causes syntax error on regexp? So using explicit contructor - // regexp above. - // selected[c].name = selected[c].projectItem.name.replace(/\.[^/.]+$/, ''); - selected[c].name = selected[c].projectItem.name.replace(regexp, ''); - } - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); -}; - -/** - * Change clip name to lower or upper case - * @param {int} case - 0 lower, 1 upper - * @return {string} result - return stringified JSON status - */ -renamer.renameChangeCase = function (caseMode) { // eslint-disable-line no-unused-vars - var selected = app.project.activeSequence.getSelection(); - if (selected.length < 1) { - app.setSDKEventMessage('nothing selected', 'error'); - return false; - } - - for (var c = 0; c < selected.length; c++) { - if (caseMode === 0) { - selected[c].name = selected[c].name.toLowerCase(); - } else { - selected[c].name = selected[c].name.toUpperCase(); - } - } - return JSON.stringify({ - 'status': 'renamed ' + selected.length + ' clips' - }); -}; - -/** - * Set Pype metadata into sequence metadata using XMP. - * This is `hackish` way to get over premiere lack of addressing unique clip on timeline, - * so we cannot store data directly per clip. - * - * @param {Object} sequence - sequence object - * @param {Object} data - to be serialized and saved - */ -renamer.setSequencePypeMetadata = function (sequence, data) { // eslint-disable-line no-unused-vars - var kPProPrivateProjectMetadataURI = 'http://ns.adobe.com/premierePrivateProjectMetaData/1.0/'; - var metadata = sequence.projectItem.getProjectMetadata(); - var pypeData = 'pypeData'; - var xmp = new XMPMeta(metadata); - var dataJSON = JSON.stringify(data); - app.project.addPropertyToProjectMetadataSchema(pypeData, 'Pype Data', 2); - - xmp.setProperty(kPProPrivateProjectMetadataURI, pypeData, dataJSON); - - var str = xmp.serialize(); - sequence.projectItem.setProjectMetadata(str, [pypeData]); - - // test - var newMetadata = sequence.projectItem.getProjectMetadata(); - var newXMP = new XMPMeta(newMetadata); - var found = newXMP.doesPropertyExist(kPProPrivateProjectMetadataURI, pypeData); - if (!found) { - app.setSDKEventMessage('metadata not set', 'error'); - } -}; - -/** - * Get Pype metadata from sequence using XMP. - * @param {Object} sequence - * @return {Object} - */ -renamer.getSequencePypeMetadata = function (sequence) { // eslint-disable-line no-unused-vars - var kPProPrivateProjectMetadataURI = 'http://ns.adobe.com/premierePrivateProjectMetaData/1.0/'; - var metadata = sequence.projectItem.getProjectMetadata(); - var pypeData = 'pypeData'; - var pypeDataN = 'Pype Data'; - var xmp = new XMPMeta(metadata); - app.project.addPropertyToProjectMetadataSchema(pypeData, pypeDataN, 2); - var pypeDataValue = xmp.getProperty(kPProPrivateProjectMetadataURI, pypeData); - if (pypeDataValue === undefined) { - var metadata = { - clips: {}, - tags: {} - }; - renamer.setSequencePypeMetadata(sequence, metadata); - pypeDataValue = xmp.getProperty(kPProPrivateProjectMetadataURI, pypeData); - return renamer.getSequencePypeMetadata(sequence); - } else { - return JSON.parse(pypeDataValue); - } -}; - -function keepExtension() { - return app.setExtensionPersistent('com.pype.rename', 0); -} - -/** - * Dispatch event with new selection - */ -renamer.activeSequenceSelectionChanged = function () { - var sel = app.project.activeSequence.getSelection(); - var selection = []; - for (var i = 0; i < sel.length; i++) { - if (sel[i].name !== 'anonymous') { - selection.push({ - 'name': sel[i].name, - 'path': sel[i].projectItem.getMediaPath() - }); - } - } - - var eoName; - if (Folder.fs === 'Macintosh') { - eoName = 'PlugPlugExternalObject'; - } else { - eoName = 'PlugPlugExternalObject.dll'; - } - - var mylib = new ExternalObject('lib:' + eoName); - - var eventObj = new CSXSEvent(); - eventObj.type = 'activeSequenceSelectionChanged'; - eventObj.data = JSON.stringify(selection); - eventObj.dispatch(); - // app.setSDKEventMessage('selection changed', 'info'); -}; - -/** - * Register active selection event dispatching - */ -renamer.registerActiveSelectionChanged = function () { - var success = app.bind('onActiveSequenceSelectionChanged', renamer.activeSequenceSelectionChanged); - return success; -}; - -keepExtension(); - -// load the XMPScript library -if (ExternalObject.AdobeXMPScript === undefined) { - ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); -} - -// var seq = app.project.activeSequence; -// renamer.getSequencePypeMetadata(seq); diff --git a/pype/hosts/premiere/extensions/com.pype.rename/lib/CEPEngine_extensions.js b/pype/hosts/premiere/extensions/com.pype.rename/lib/CEPEngine_extensions.js deleted file mode 100644 index 04f5516a2d..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/lib/CEPEngine_extensions.js +++ /dev/null @@ -1,699 +0,0 @@ -/************************************************************************************************** -* -* ADOBE SYSTEMS INCORPORATED -* Copyright 2013 Adobe Systems Incorporated -* All Rights Reserved. -* -* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the -* terms of the Adobe license agreement accompanying it. If you have received this file from a -* source other than Adobe, then your use, modification, or distribution of it requires the prior -* written permission of Adobe. -* -**************************************************************************************************/ - -// This is the JavaScript code for bridging to native functionality -// See CEPEngine_extensions.cpp for implementation of native methods. -// -// Note: So far all native file i/o functions are synchronous, and aynchronous file i/o is TBD. - -/** Version v8.0.0 */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, native */ - -var cep; -if (!cep) { - cep = {}; -} -if (!cep.fs) { - cep.fs = {}; -} -if (!cep.process) { - cep.process = {}; -} -if (!cep.encoding) { - cep.encoding = {}; -} -if (!cep.util) { - cep.util = {}; -} -(function () { - // Internal function to get the last error code. - native function GetLastError(); - function getLastError() { - return GetLastError(); - } - - function getErrorResult(){ - var result = {err: getLastError()}; - return result; - } - - // Error values. These MUST be in sync with the error values - // at the top of CEPEngine_extensions.cpp - - /** - * @constant No error. - */ - cep.fs.NO_ERROR = 0; - - /** - * @constant Unknown error occurred. - */ - cep.fs.ERR_UNKNOWN = 1; - - /** - * @constant Invalid parameters passed to function. - */ - cep.fs.ERR_INVALID_PARAMS = 2; - - /** - * @constant File or directory was not found. - */ - cep.fs.ERR_NOT_FOUND = 3; - - /** - * @constant File or directory could not be read. - */ - cep.fs.ERR_CANT_READ = 4; - - /** - * @constant An unsupported encoding value was specified. - */ - cep.fs.ERR_UNSUPPORTED_ENCODING = 5; - - /** - * @constant File could not be written. - */ - cep.fs.ERR_CANT_WRITE = 6; - - /** - * @constant Target directory is out of space. File could not be written. - */ - cep.fs.ERR_OUT_OF_SPACE = 7; - - /** - * @constant Specified path does not point to a file. - */ - cep.fs.ERR_NOT_FILE = 8; - - /** - * @constant Specified path does not point to a directory. - */ - cep.fs.ERR_NOT_DIRECTORY = 9; - - /** - * @constant Specified file already exists. - */ - cep.fs.ERR_FILE_EXISTS = 10; - - /** - * @constant The maximum number of processes has been exceeded. - */ - cep.process.ERR_EXCEED_MAX_NUM_PROCESS = 101; - - /** - * @constant Invalid URL. - */ - cep.util.ERR_INVALID_URL = 201; - - /** - * @constant deprecated API. - */ - cep.util.DEPRECATED_API = 202; - - /** - * @constant UTF8 encoding type. - */ - cep.encoding.UTF8 = "UTF-8"; - - /** - * @constant Base64 encoding type. - */ - cep.encoding.Base64 = "Base64"; - - /** - * Displays the OS File Open dialog, allowing the user to select files or directories. - * - * @param allowMultipleSelection {boolean} When true, multiple files/folders can be selected. - * @param chooseDirectory {boolean} When true, only folders can be selected. When false, only - * files can be selected. - * @param title {string} Title of the open dialog. - * @param initialPath {string} Initial path to display in the dialog. Pass NULL or "" to - * display the last path chosen. - * @param fileTypes {Array.} The file extensions (without the dot) for the types - * of files that can be selected. Ignored when chooseDirectory=true. - * - * @return An object with these properties: - *
  • "data": An array of the full names of the selected files.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_INVALID_PARAMS
  • - *
- **/ - native function ShowOpenDialog(); - cep.fs.showOpenDialog = function (allowMultipleSelection, chooseDirectory, title, initialPath, fileTypes) { - var resultString = ShowOpenDialog(allowMultipleSelection, chooseDirectory, - title || 'Open', initialPath || '', - fileTypes ? fileTypes.join(' ') : ''); - - var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; - return result; - }; - - /** - * Displays the OS File Open dialog, allowing the user to select files or directories. - * - * @param allowMultipleSelection {boolean} When true, multiple files/folders can be selected. - * @param chooseDirectory {boolean} When true, only folders can be selected. When false, only - * files can be selected. - * @param title {string} Title of the open dialog. - * @param initialPath {string} Initial path to display in the dialog. Pass NULL or "" to - * display the last path chosen. - * @param fileTypes {Array.} The file extensions (without the dot) for the types - * of files that can be selected. Ignored when chooseDirectory=true. - * @param friendlyFilePrefix {string} String to put in front of the extensions - * of files that can be selected. Ignored when chooseDirectory=true. (win only) - * For example: - * fileTypes = ["gif", "jpg", "jpeg", "png", "bmp", "webp", "svg"]; - * friendlyFilePrefix = "Images (*.gif;*.jpg;*.jpeg;*.png;*.bmp;*.webp;*.svg)"; - * @param prompt {string} String for OK button (mac only, default is "Open" on mac, "Open" or "Select Folder" on win). - * - * @return An object with these properties: - *
  • "data": An array of the full names of the selected files.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_INVALID_PARAMS
  • - *
- **/ - native function ShowOpenDialogEx(); - cep.fs.showOpenDialogEx = function (allowMultipleSelection, chooseDirectory, title, initialPath, fileTypes, - friendlyFilePrefix, prompt) { - var resultString = ShowOpenDialogEx(allowMultipleSelection, chooseDirectory, - title || 'Open', initialPath || '', - fileTypes ? fileTypes.join(' ') : '', friendlyFilePrefix || '', - prompt || ''); - - var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; - return result; - }; - - /** - * Displays the OS File Save dialog, allowing the user to type in a file name. - * - * @param title {string} Title of the save dialog. - * @param initialPath {string} Initial path to display in the dialog. Pass NULL or "" to - * display the last path chosen. - * @param fileTypes {Array.} The file extensions (without the dot) for the types - * of files that can be selected. - * @param defaultName {string} String to start with for the file name. - * @param friendlyFilePrefix {string} String to put in front of the extensions of files that can be selected. (win only) - * For example: - * fileTypes = ["gif", "jpg", "jpeg", "png", "bmp", "webp", "svg"]; - * friendlyFilePrefix = "Images (*.gif;*.jpg;*.jpeg;*.png;*.bmp;*.webp;*.svg)"; - * @param prompt {string} String for Save button (mac only, default is "Save" on mac and win). - * @param nameFieldLabel {string} String displayed in front of the file name text field (mac only, "File name:" on win). - * - * @return An object with these properties: - *
  • "data": The file path selected to save at or "" if canceled
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_INVALID_PARAMS
  • - *
- **/ - native function ShowSaveDialogEx(); - cep.fs.showSaveDialogEx = function (title, initialPath, fileTypes, defaultName, friendlyFilePrefix, prompt, nameFieldLabel) { - var resultString = ShowSaveDialogEx(title || '', initialPath || '', - fileTypes ? fileTypes.join(' ') : '', defaultName || '', - friendlyFilePrefix || '', prompt || '', nameFieldLabel || ''); - - var result = {data: resultString || '', err: getLastError() }; - return result; - }; - - /** - * Reads the contents of a folder. - * - * @param path {string} The path of the folder to read. - * - * @return An object with these properties: - *
  • "data": An array of the names of the contained files (excluding '.' and '..'.
  • - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_NOT_FOUND - *
    ERR_CANT_READ
- **/ - native function ReadDir(); - cep.fs.readdir = function (path) { - var resultString = ReadDir(path); - var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; - return result; - }; - - /** - * Creates a new folder. - * - * @param path {string} The path of the folder to create. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS
- **/ - native function MakeDir(); - cep.fs.makedir = function (path) { - MakeDir(path); - return getErrorResult(); - }; - - /** - * Renames a file or folder. - * - * @param oldPath {string} The old name of the file or folder. - * @param newPath {string} The new name of the file or folder. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_NOT_FOUND - *
    ERR_FILE_EXISTS
- **/ - native function Rename(); - cep.fs.rename = function(oldPath, newPath) { - Rename(oldPath, newPath); - return getErrorResult(); - }; - - /** - * Reports whether an item is a file or folder. - * - * @param path {string} The path of the file or folder. - * - * @return An object with these properties: - *
  • "data": An object with properties - *
    isFile (boolean) - *
    isDirectory (boolean) - *
    mtime (modification DateTime)
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_NOT_FOUND
  • - *
- **/ - native function IsDirectory(); - native function GetFileModificationTime(); - cep.fs.stat = function (path) { - var isDir = IsDirectory(path); - var modtime = GetFileModificationTime(path); - var result = { - data: { - isFile: function () { - return !isDir; - }, - isDirectory: function () { - return isDir; - }, - mtime: modtime - }, - err: getLastError() - }; - - return result; - }; - - /** - * Reads the entire contents of a file. - * - * @param path {string} The path of the file to read. - * @param encoding {string} The encoding of the contents of file, one of - * UTF8 (the default) or Base64. - * - * @return An object with these properties: - *
  • "data": The file contents.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_NOT_FOUND - *
    ERR_CANT_READ - *
    ERR_UNSUPPORTED_ENCODING
  • - *
- **/ - native function ReadFile(); - cep.fs.readFile = function (path, encoding) { - encoding = encoding ? encoding : cep.encoding.UTF8; - var contents = ReadFile(path, encoding); - var result = {data: contents, err: getLastError() }; - return result; - }; - - /** - * Writes data to a file, replacing the file if it already exists. - * - * @param path {string} The path of the file to write. - * @param data {string} The data to write to the file. - * @param encoding {string} The encoding of the contents of file, one of - * UTF8 (the default) or Base64. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_UNSUPPORTED_ENCODING - *
    ERR_CANT_WRITE - *
    ERR_OUT_OF_SPACE
- **/ - native function WriteFile(); - cep.fs.writeFile = function (path, data, encoding) { - encoding = encoding ? encoding : cep.encoding.UTF8; - WriteFile(path, data, encoding); - return getErrorResult(); - }; - - /** - * Sets permissions for a file or folder. - * - * @param path {string} The path of the file or folder. - * @param mode {number} The permissions in numeric format (for example, 0777). - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_CANT_WRITE
- **/ - native function SetPosixPermissions(); - cep.fs.chmod = function (path, mode) { - SetPosixPermissions(path, mode); - return getErrorResult(); - }; - - /** - * Deletes a file. - * - * @param path {string} The path of the file to delete. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_NOT_FOUND - *
    ERR_NOT_FILE
- **/ - native function DeleteFileOrDirectory(); - native function IsDirectory(); - cep.fs.deleteFile = function (path) { - if (IsDirectory(path)) { - var result = {err: cep.fs.ERR_NOT_FILE}; - return result; - } - DeleteFileOrDirectory(path); - return getErrorResult(); - }; - - /** - * Creates a process. - * - * @param arguments {list} The arguments to create process. The first one is the full path of the executable, - * followed by the arguments of the executable. - * - * @return An object with these properties: - *
  • "data": The pid of the process, or -1 on error.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_EXCEED_MAX_NUM_PROCESS - *
    ERR_NOT_FOUND - *
    ERR_NOT_FILE
  • - *
- **/ - native function CreateProcess(); - cep.process.createProcess = function () { - var args = Array.prototype.slice.call(arguments); - var pid = CreateProcess(args); - var result = {data: pid, err: getLastError()}; - return result; - }; - - /** - * Registers a standard-output handler for a process. - * - * @param pid {int} The pid of the process. - * @param callback {function} The handler function for the standard output callback. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function SetupStdOutHandler(); - cep.process.stdout = function (pid, callback) { - SetupStdOutHandler(pid, callback); - return getErrorResult(); - }; - - /** - * Registers up a standard-error handler for a process. - * - * @param pid {int} The pid of the process. - * @param callback {function} The handler function for the standard error callback. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function SetupStdErrHandler(); - cep.process.stderr = function (pid, callback) { - SetupStdErrHandler(pid, callback); - return getErrorResult(); - }; - - /** - * Writes data to the standard input of a process. - * - * @param pid {int} The pid of the process - * @param data {string} The data to write. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function WriteStdIn(); - cep.process.stdin = function (pid, data) { - WriteStdIn(pid, data); - return getErrorResult(); - }; - - /** - * Retrieves the working directory of a process. - * - * @param pid {int} The pid of the process. - * - * @return An object with these properties: - *
  • "data": The path of the working directory.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function GetWorkingDirectory(); - cep.process.getWorkingDirectory = function (pid) { - var wd = GetWorkingDirectory(pid); - var result = {data: wd, err: getLastError()}; - return result; - }; - - /** - * Waits for a process to quit. - * - * @param pid {int} The pid of the process. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function WaitFor(); - cep.process.waitfor = function (pid) { - WaitFor(pid); - return getErrorResult(); - }; - - /** - * Registers a handler for the onquit callback of a process. - * - * @param pid {int} The pid of the process. - * @param callback {function} The handler function. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function OnQuit(); - cep.process.onquit = function (pid, callback) { - OnQuit(pid, callback); - return getErrorResult(); - }; - - /** - * Reports whether a process is currently running. - * - * @param pid {int} The pid of the process. - * - * @return An object with these properties: - *
  • "data": True if the process is running, false otherwise.
  • - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function IsRunning(); - cep.process.isRunning = function (pid) { - var isRunning = IsRunning(pid); - var result = {data: isRunning, err: getLastError()}; - return result; - }; - - /** - * Terminates a process. - * - * @param pid {int} The pid of the process - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS - *
    ERR_INVALID_PROCESS_ID
- **/ - native function Terminate(); - cep.process.terminate = function (pid) { - Terminate(pid); - return getErrorResult(); - }; - - /** - * Encoding conversions. - * - */ - cep.encoding.convertion = - { - utf8_to_b64: function(str) { - return window.btoa(unescape(encodeURIComponent(str))); - }, - - b64_to_utf8: function(base64str) { - // If a base64 string contains any whitespace character, DOM Exception 5 occurs during window.atob, please see - // http://stackoverflow.com/questions/14695988/dom-exception-5-invalid-character-error-on-valid-base64-image-string-in-javascri - base64str = base64str.replace(/\s/g, ''); - return decodeURIComponent(escape(window.atob(base64str))); - }, - - binary_to_b64: function(binary) { - return window.btoa(binary); - }, - - b64_to_binary: function(base64str) { - return window.atob(base64str); - }, - - ascii_to_b64: function(ascii) { - return window.btoa(binary); - }, - - b64_to_ascii: function(base64str) { - return window.atob(base64str); - } - }; - - /** - * Opens a page in the default system browser. - * - * @param url {string} The URL of the page/file to open, or the email address. - * Must use HTTP/HTTPS/file/mailto. For example: - * "http://www.adobe.com" - * "https://github.com" - * "file:///C:/log.txt" - * "mailto:test@adobe.com" - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_UNKNOWN - *
    ERR_INVALID_PARAMS
- **/ - native function OpenURLInDefaultBrowser(); - cep.util.openURLInDefaultBrowser = function (url) { - if (url && (url.indexOf("http://") === 0 || - url.indexOf("https://") === 0 || - url.indexOf("file://") === 0 || - url.indexOf("mailto:") === 0)) { - OpenURLInDefaultBrowser(url); - return getErrorResult(); - } else { - return { err : cep.util.ERR_INVALID_URL }; - } - }; - - /** - * Registers a callback function for extension unload. If called more than once, - * the last callback that is successfully registered is used. - * - * @deprecated since version 6.0.0 - * - * @param callback {function} The handler function. - * - * @return An object with this property: - *
  • "err": The status of the operation, one of: - *
    NO_ERROR - *
    ERR_INVALID_PARAMS
- **/ - native function RegisterExtensionUnloadCallback(); - cep.util.registerExtensionUnloadCallback = function (callback) { - return { err : cep.util.DEPRECATED_API }; - }; - - /** - * Stores the user's proxy credentials - * - * @param username {string} proxy username - * @param password {string} proxy password - * - * @return An object with this property: - *
  • "err": The status of the operation, one of - *
    NO_ERROR - *
    ERR_INVALID_PARAMS
  • - *
- **/ - native function StoreProxyCredentials(); - cep.util.storeProxyCredentials = function (username, password) { - StoreProxyCredentials(username, password); - return getErrorResult(); - }; - -})(); diff --git a/pype/hosts/premiere/extensions/com.pype.rename/lib/CSInterface.js b/pype/hosts/premiere/extensions/com.pype.rename/lib/CSInterface.js deleted file mode 100644 index e2a6e02eb2..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/lib/CSInterface.js +++ /dev/null @@ -1,1291 +0,0 @@ -/************************************************************************************************** -* -* ADOBE SYSTEMS INCORPORATED -* Copyright 2013 Adobe Systems Incorporated -* All Rights Reserved. -* -* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the -* terms of the Adobe license agreement accompanying it. If you have received this file from a -* source other than Adobe, then your use, modification, or distribution of it requires the prior -* written permission of Adobe. -* -**************************************************************************************************/ - -/** CSInterface - v9.2.0 */ - -/** - * Stores constants for the window types supported by the CSXS infrastructure. - */ -function CSXSWindowType() -{ -} - -/** Constant for the CSXS window type Panel. */ -CSXSWindowType._PANEL = "Panel"; - -/** Constant for the CSXS window type Modeless. */ -CSXSWindowType._MODELESS = "Modeless"; - -/** Constant for the CSXS window type ModalDialog. */ -CSXSWindowType._MODAL_DIALOG = "ModalDialog"; - -/** EvalScript error message */ -EvalScript_ErrMessage = "EvalScript error."; - -/** - * @class Version - * Defines a version number with major, minor, micro, and special - * components. The major, minor and micro values are numeric; the special - * value can be any string. - * - * @param major The major version component, a positive integer up to nine digits long. - * @param minor The minor version component, a positive integer up to nine digits long. - * @param micro The micro version component, a positive integer up to nine digits long. - * @param special The special version component, an arbitrary string. - * - * @return A new \c Version object. - */ -function Version(major, minor, micro, special) -{ - this.major = major; - this.minor = minor; - this.micro = micro; - this.special = special; -} - -/** - * The maximum value allowed for a numeric version component. - * This reflects the maximum value allowed in PlugPlug and the manifest schema. - */ -Version.MAX_NUM = 999999999; - -/** - * @class VersionBound - * Defines a boundary for a version range, which associates a \c Version object - * with a flag for whether it is an inclusive or exclusive boundary. - * - * @param version The \c #Version object. - * @param inclusive True if this boundary is inclusive, false if it is exclusive. - * - * @return A new \c VersionBound object. - */ -function VersionBound(version, inclusive) -{ - this.version = version; - this.inclusive = inclusive; -} - -/** - * @class VersionRange - * Defines a range of versions using a lower boundary and optional upper boundary. - * - * @param lowerBound The \c #VersionBound object. - * @param upperBound The \c #VersionBound object, or null for a range with no upper boundary. - * - * @return A new \c VersionRange object. - */ -function VersionRange(lowerBound, upperBound) -{ - this.lowerBound = lowerBound; - this.upperBound = upperBound; -} - -/** - * @class Runtime - * Represents a runtime related to the CEP infrastructure. - * Extensions can declare dependencies on particular - * CEP runtime versions in the extension manifest. - * - * @param name The runtime name. - * @param version A \c #VersionRange object that defines a range of valid versions. - * - * @return A new \c Runtime object. - */ -function Runtime(name, versionRange) -{ - this.name = name; - this.versionRange = versionRange; -} - -/** -* @class Extension -* Encapsulates a CEP-based extension to an Adobe application. -* -* @param id The unique identifier of this extension. -* @param name The localizable display name of this extension. -* @param mainPath The path of the "index.html" file. -* @param basePath The base path of this extension. -* @param windowType The window type of the main window of this extension. - Valid values are defined by \c #CSXSWindowType. -* @param width The default width in pixels of the main window of this extension. -* @param height The default height in pixels of the main window of this extension. -* @param minWidth The minimum width in pixels of the main window of this extension. -* @param minHeight The minimum height in pixels of the main window of this extension. -* @param maxWidth The maximum width in pixels of the main window of this extension. -* @param maxHeight The maximum height in pixels of the main window of this extension. -* @param defaultExtensionDataXml The extension data contained in the default \c ExtensionDispatchInfo section of the extension manifest. -* @param specialExtensionDataXml The extension data contained in the application-specific \c ExtensionDispatchInfo section of the extension manifest. -* @param requiredRuntimeList An array of \c Runtime objects for runtimes required by this extension. -* @param isAutoVisible True if this extension is visible on loading. -* @param isPluginExtension True if this extension has been deployed in the Plugins folder of the host application. -* -* @return A new \c Extension object. -*/ -function Extension(id, name, mainPath, basePath, windowType, width, height, minWidth, minHeight, maxWidth, maxHeight, - defaultExtensionDataXml, specialExtensionDataXml, requiredRuntimeList, isAutoVisible, isPluginExtension) -{ - this.id = id; - this.name = name; - this.mainPath = mainPath; - this.basePath = basePath; - this.windowType = windowType; - this.width = width; - this.height = height; - this.minWidth = minWidth; - this.minHeight = minHeight; - this.maxWidth = maxWidth; - this.maxHeight = maxHeight; - this.defaultExtensionDataXml = defaultExtensionDataXml; - this.specialExtensionDataXml = specialExtensionDataXml; - this.requiredRuntimeList = requiredRuntimeList; - this.isAutoVisible = isAutoVisible; - this.isPluginExtension = isPluginExtension; -} - -/** - * @class CSEvent - * A standard JavaScript event, the base class for CEP events. - * - * @param type The name of the event type. - * @param scope The scope of event, can be "GLOBAL" or "APPLICATION". - * @param appId The unique identifier of the application that generated the event. - * @param extensionId The unique identifier of the extension that generated the event. - * - * @return A new \c CSEvent object - */ -function CSEvent(type, scope, appId, extensionId) -{ - this.type = type; - this.scope = scope; - this.appId = appId; - this.extensionId = extensionId; -} - -/** Event-specific data. */ -CSEvent.prototype.data = ""; - -/** - * @class SystemPath - * Stores operating-system-specific location constants for use in the - * \c #CSInterface.getSystemPath() method. - * @return A new \c SystemPath object. - */ -function SystemPath() -{ -} - -/** The path to user data. */ -SystemPath.USER_DATA = "userData"; - -/** The path to common files for Adobe applications. */ -SystemPath.COMMON_FILES = "commonFiles"; - -/** The path to the user's default document folder. */ -SystemPath.MY_DOCUMENTS = "myDocuments"; - -/** @deprecated. Use \c #SystemPath.Extension. */ -SystemPath.APPLICATION = "application"; - -/** The path to current extension. */ -SystemPath.EXTENSION = "extension"; - -/** The path to hosting application's executable. */ -SystemPath.HOST_APPLICATION = "hostApplication"; - -/** - * @class ColorType - * Stores color-type constants. - */ -function ColorType() -{ -} - -/** RGB color type. */ -ColorType.RGB = "rgb"; - -/** Gradient color type. */ -ColorType.GRADIENT = "gradient"; - -/** Null color type. */ -ColorType.NONE = "none"; - -/** - * @class RGBColor - * Stores an RGB color with red, green, blue, and alpha values. - * All values are in the range [0.0 to 255.0]. Invalid numeric values are - * converted to numbers within this range. - * - * @param red The red value, in the range [0.0 to 255.0]. - * @param green The green value, in the range [0.0 to 255.0]. - * @param blue The blue value, in the range [0.0 to 255.0]. - * @param alpha The alpha (transparency) value, in the range [0.0 to 255.0]. - * The default, 255.0, means that the color is fully opaque. - * - * @return A new RGBColor object. - */ -function RGBColor(red, green, blue, alpha) -{ - this.red = red; - this.green = green; - this.blue = blue; - this.alpha = alpha; -} - -/** - * @class Direction - * A point value in which the y component is 0 and the x component - * is positive or negative for a right or left direction, - * or the x component is 0 and the y component is positive or negative for - * an up or down direction. - * - * @param x The horizontal component of the point. - * @param y The vertical component of the point. - * - * @return A new \c Direction object. - */ -function Direction(x, y) -{ - this.x = x; - this.y = y; -} - -/** - * @class GradientStop - * Stores gradient stop information. - * - * @param offset The offset of the gradient stop, in the range [0.0 to 1.0]. - * @param rgbColor The color of the gradient at this point, an \c #RGBColor object. - * - * @return GradientStop object. - */ -function GradientStop(offset, rgbColor) -{ - this.offset = offset; - this.rgbColor = rgbColor; -} - -/** - * @class GradientColor - * Stores gradient color information. - * - * @param type The gradient type, must be "linear". - * @param direction A \c #Direction object for the direction of the gradient - (up, down, right, or left). - * @param numStops The number of stops in the gradient. - * @param gradientStopList An array of \c #GradientStop objects. - * - * @return A new \c GradientColor object. - */ -function GradientColor(type, direction, numStops, arrGradientStop) -{ - this.type = type; - this.direction = direction; - this.numStops = numStops; - this.arrGradientStop = arrGradientStop; -} - -/** - * @class UIColor - * Stores color information, including the type, anti-alias level, and specific color - * values in a color object of an appropriate type. - * - * @param type The color type, 1 for "rgb" and 2 for "gradient". - The supplied color object must correspond to this type. - * @param antialiasLevel The anti-alias level constant. - * @param color A \c #RGBColor or \c #GradientColor object containing specific color information. - * - * @return A new \c UIColor object. - */ -function UIColor(type, antialiasLevel, color) -{ - this.type = type; - this.antialiasLevel = antialiasLevel; - this.color = color; -} - -/** - * @class AppSkinInfo - * Stores window-skin properties, such as color and font. All color parameter values are \c #UIColor objects except that systemHighlightColor is \c #RGBColor object. - * - * @param baseFontFamily The base font family of the application. - * @param baseFontSize The base font size of the application. - * @param appBarBackgroundColor The application bar background color. - * @param panelBackgroundColor The background color of the extension panel. - * @param appBarBackgroundColorSRGB The application bar background color, as sRGB. - * @param panelBackgroundColorSRGB The background color of the extension panel, as sRGB. - * @param systemHighlightColor The highlight color of the extension panel, if provided by the host application. Otherwise, the operating-system highlight color. - * - * @return AppSkinInfo object. - */ -function AppSkinInfo(baseFontFamily, baseFontSize, appBarBackgroundColor, panelBackgroundColor, appBarBackgroundColorSRGB, panelBackgroundColorSRGB, systemHighlightColor) -{ - this.baseFontFamily = baseFontFamily; - this.baseFontSize = baseFontSize; - this.appBarBackgroundColor = appBarBackgroundColor; - this.panelBackgroundColor = panelBackgroundColor; - this.appBarBackgroundColorSRGB = appBarBackgroundColorSRGB; - this.panelBackgroundColorSRGB = panelBackgroundColorSRGB; - this.systemHighlightColor = systemHighlightColor; -} - -/** - * @class HostEnvironment - * Stores information about the environment in which the extension is loaded. - * - * @param appName The application's name. - * @param appVersion The application's version. - * @param appLocale The application's current license locale. - * @param appUILocale The application's current UI locale. - * @param appId The application's unique identifier. - * @param isAppOnline True if the application is currently online. - * @param appSkinInfo An \c #AppSkinInfo object containing the application's default color and font styles. - * - * @return A new \c HostEnvironment object. - */ -function HostEnvironment(appName, appVersion, appLocale, appUILocale, appId, isAppOnline, appSkinInfo) -{ - this.appName = appName; - this.appVersion = appVersion; - this.appLocale = appLocale; - this.appUILocale = appUILocale; - this.appId = appId; - this.isAppOnline = isAppOnline; - this.appSkinInfo = appSkinInfo; -} - -/** - * @class HostCapabilities - * Stores information about the host capabilities. - * - * @param EXTENDED_PANEL_MENU True if the application supports panel menu. - * @param EXTENDED_PANEL_ICONS True if the application supports panel icon. - * @param DELEGATE_APE_ENGINE True if the application supports delegated APE engine. - * @param SUPPORT_HTML_EXTENSIONS True if the application supports HTML extensions. - * @param DISABLE_FLASH_EXTENSIONS True if the application disables FLASH extensions. - * - * @return A new \c HostCapabilities object. - */ -function HostCapabilities(EXTENDED_PANEL_MENU, EXTENDED_PANEL_ICONS, DELEGATE_APE_ENGINE, SUPPORT_HTML_EXTENSIONS, DISABLE_FLASH_EXTENSIONS) -{ - this.EXTENDED_PANEL_MENU = EXTENDED_PANEL_MENU; - this.EXTENDED_PANEL_ICONS = EXTENDED_PANEL_ICONS; - this.DELEGATE_APE_ENGINE = DELEGATE_APE_ENGINE; - this.SUPPORT_HTML_EXTENSIONS = SUPPORT_HTML_EXTENSIONS; - this.DISABLE_FLASH_EXTENSIONS = DISABLE_FLASH_EXTENSIONS; // Since 5.0.0 -} - -/** - * @class ApiVersion - * Stores current api version. - * - * Since 4.2.0 - * - * @param major The major version - * @param minor The minor version. - * @param micro The micro version. - * - * @return ApiVersion object. - */ -function ApiVersion(major, minor, micro) -{ - this.major = major; - this.minor = minor; - this.micro = micro; -} - -/** - * @class MenuItemStatus - * Stores flyout menu item status - * - * Since 5.2.0 - * - * @param menuItemLabel The menu item label. - * @param enabled True if user wants to enable the menu item. - * @param checked True if user wants to check the menu item. - * - * @return MenuItemStatus object. - */ -function MenuItemStatus(menuItemLabel, enabled, checked) -{ - this.menuItemLabel = menuItemLabel; - this.enabled = enabled; - this.checked = checked; -} - -/** - * @class ContextMenuItemStatus - * Stores the status of the context menu item. - * - * Since 5.2.0 - * - * @param menuItemID The menu item id. - * @param enabled True if user wants to enable the menu item. - * @param checked True if user wants to check the menu item. - * - * @return MenuItemStatus object. - */ -function ContextMenuItemStatus(menuItemID, enabled, checked) -{ - this.menuItemID = menuItemID; - this.enabled = enabled; - this.checked = checked; -} -//------------------------------ CSInterface ---------------------------------- - -/** - * @class CSInterface - * This is the entry point to the CEP extensibility infrastructure. - * Instantiate this object and use it to: - *
    - *
  • Access information about the host application in which an extension is running
  • - *
  • Launch an extension
  • - *
  • Register interest in event notifications, and dispatch events
  • - *
- * - * @return A new \c CSInterface object - */ -function CSInterface() -{ -} - -/** - * User can add this event listener to handle native application theme color changes. - * Callback function gives extensions ability to fine-tune their theme color after the - * global theme color has been changed. - * The callback function should be like below: - * - * @example - * // event is a CSEvent object, but user can ignore it. - * function OnAppThemeColorChanged(event) - * { - * // Should get a latest HostEnvironment object from application. - * var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; - * // Gets the style information such as color info from the skinInfo, - * // and redraw all UI controls of your extension according to the style info. - * } - */ -CSInterface.THEME_COLOR_CHANGED_EVENT = "com.adobe.csxs.events.ThemeColorChanged"; - -/** The host environment data object. */ -CSInterface.prototype.hostEnvironment = window.__adobe_cep__ ? JSON.parse(window.__adobe_cep__.getHostEnvironment()) : null; - -/** Retrieves information about the host environment in which the - * extension is currently running. - * - * @return A \c #HostEnvironment object. - */ -CSInterface.prototype.getHostEnvironment = function() -{ - this.hostEnvironment = JSON.parse(window.__adobe_cep__.getHostEnvironment()); - return this.hostEnvironment; -}; - -/** Loads binary file created which is located at url asynchronously -* -*@param urlName url at which binary file is located. Local files should start with 'file://' -*@param callback Optional. A callback function that returns after binary is loaded - -*@example -* To create JS binary use command ./cep_compiler test.js test.bin -* To load JS binary asyncronously -* var CSLib = new CSInterface(); -* CSLib.loadBinAsync(url, function () { }); -*/ -CSInterface.prototype.loadBinAsync = function(urlName,callback) -{ - try - { - var xhr = new XMLHttpRequest(); - xhr.responseType = 'arraybuffer'; // make response as ArrayBuffer - xhr.open('GET', urlName, true); - xhr.onerror = function () - { - console.log("Unable to load snapshot from given URL"); - return false; - }; - xhr.send(); - xhr.onload = () => { - window.__adobe_cep__.loadSnapshot(xhr.response); - if (typeof callback === "function") - { - callback(); - } - else if(typeof callback !== "undefined") - { - console.log("Provided callback is not a function"); - } - } - } - catch(err) - { - console.log(err); - return false; - } - - return true; -}; - -/** Loads binary file created synchronously -* -*@param pathName the local path at which binary file is located - -*@example -* To create JS binary use command ./cep_compiler test.js test.bin -* To load JS binary syncronously -* var CSLib = new CSInterface(); -* CSLib.loadBinSync(path); -*/ -CSInterface.prototype.loadBinSync = function(pathName) -{ - try - { - var OSVersion = this.getOSInformation(); - if(pathName.startsWith("file://")) - { - if (OSVersion.indexOf("Windows") >= 0) - { - pathName = pathName.replace("file:///", ""); - } - else if (OSVersion.indexOf("Mac") >= 0) - { - pathName = pathName.replace("file://", ""); - } - window.__adobe_cep__.loadSnapshot(pathName); - return true; - } - } - catch(err) - { - console.log(err); - return false; - } - //control should not come here - return false; -}; - -/** Closes this extension. */ -CSInterface.prototype.closeExtension = function() -{ - window.__adobe_cep__.closeExtension(); -}; - -/** - * Retrieves a path for which a constant is defined in the system. - * - * @param pathType The path-type constant defined in \c #SystemPath , - * - * @return The platform-specific system path string. - */ -CSInterface.prototype.getSystemPath = function(pathType) -{ - var path = decodeURI(window.__adobe_cep__.getSystemPath(pathType)); - var OSVersion = this.getOSInformation(); - if (OSVersion.indexOf("Windows") >= 0) - { - path = path.replace("file:///", ""); - } - else if (OSVersion.indexOf("Mac") >= 0) - { - path = path.replace("file://", ""); - } - return path; -}; - -/** - * Evaluates a JavaScript script, which can use the JavaScript DOM - * of the host application. - * - * @param script The JavaScript script. - * @param callback Optional. A callback function that receives the result of execution. - * If execution fails, the callback function receives the error message \c EvalScript_ErrMessage. - */ -CSInterface.prototype.evalScript = function(script, callback) -{ - if(callback === null || callback === undefined) - { - callback = function(result){}; - } - window.__adobe_cep__.evalScript(script, callback); -}; - -/** - * Retrieves the unique identifier of the application. - * in which the extension is currently running. - * - * @return The unique ID string. - */ -CSInterface.prototype.getApplicationID = function() -{ - var appId = this.hostEnvironment.appId; - return appId; -}; - -/** - * Retrieves host capability information for the application - * in which the extension is currently running. - * - * @return A \c #HostCapabilities object. - */ -CSInterface.prototype.getHostCapabilities = function() -{ - var hostCapabilities = JSON.parse(window.__adobe_cep__.getHostCapabilities() ); - return hostCapabilities; -}; - -/** - * Triggers a CEP event programmatically. Yoy can use it to dispatch - * an event of a predefined type, or of a type you have defined. - * - * @param event A \c CSEvent object. - */ -CSInterface.prototype.dispatchEvent = function(event) -{ - if (typeof event.data == "object") - { - event.data = JSON.stringify(event.data); - } - - window.__adobe_cep__.dispatchEvent(event); -}; - -/** - * Registers an interest in a CEP event of a particular type, and - * assigns an event handler. - * The event infrastructure notifies your extension when events of this type occur, - * passing the event object to the registered handler function. - * - * @param type The name of the event type of interest. - * @param listener The JavaScript handler function or method. - * @param obj Optional, the object containing the handler method, if any. - * Default is null. - */ -CSInterface.prototype.addEventListener = function(type, listener, obj) -{ - window.__adobe_cep__.addEventListener(type, listener, obj); -}; - -/** - * Removes a registered event listener. - * - * @param type The name of the event type of interest. - * @param listener The JavaScript handler function or method that was registered. - * @param obj Optional, the object containing the handler method, if any. - * Default is null. - */ -CSInterface.prototype.removeEventListener = function(type, listener, obj) -{ - window.__adobe_cep__.removeEventListener(type, listener, obj); -}; - -/** - * Loads and launches another extension, or activates the extension if it is already loaded. - * - * @param extensionId The extension's unique identifier. - * @param startupParams Not currently used, pass "". - * - * @example - * To launch the extension "help" with ID "HLP" from this extension, call: - * requestOpenExtension("HLP", ""); - * - */ -CSInterface.prototype.requestOpenExtension = function(extensionId, params) -{ - window.__adobe_cep__.requestOpenExtension(extensionId, params); -}; - -/** - * Retrieves the list of extensions currently loaded in the current host application. - * The extension list is initialized once, and remains the same during the lifetime - * of the CEP session. - * - * @param extensionIds Optional, an array of unique identifiers for extensions of interest. - * If omitted, retrieves data for all extensions. - * - * @return Zero or more \c #Extension objects. - */ -CSInterface.prototype.getExtensions = function(extensionIds) -{ - var extensionIdsStr = JSON.stringify(extensionIds); - var extensionsStr = window.__adobe_cep__.getExtensions(extensionIdsStr); - - var extensions = JSON.parse(extensionsStr); - return extensions; -}; - -/** - * Retrieves network-related preferences. - * - * @return A JavaScript object containing network preferences. - */ -CSInterface.prototype.getNetworkPreferences = function() -{ - var result = window.__adobe_cep__.getNetworkPreferences(); - var networkPre = JSON.parse(result); - - return networkPre; -}; - -/** - * Initializes the resource bundle for this extension with property values - * for the current application and locale. - * To support multiple locales, you must define a property file for each locale, - * containing keyed display-string values for that locale. - * See localization documentation for Extension Builder and related products. - * - * Keys can be in the - * form key.value="localized string", for use in HTML text elements. - * For example, in this input element, the localized \c key.value string is displayed - * instead of the empty \c value string: - * - * - * - * @return An object containing the resource bundle information. - */ -CSInterface.prototype.initResourceBundle = function() -{ - var resourceBundle = JSON.parse(window.__adobe_cep__.initResourceBundle()); - var resElms = document.querySelectorAll('[data-locale]'); - for (var n = 0; n < resElms.length; n++) - { - var resEl = resElms[n]; - // Get the resource key from the element. - var resKey = resEl.getAttribute('data-locale'); - if (resKey) - { - // Get all the resources that start with the key. - for (var key in resourceBundle) - { - if (key.indexOf(resKey) === 0) - { - var resValue = resourceBundle[key]; - if (key.length == resKey.length) - { - resEl.innerHTML = resValue; - } - else if ('.' == key.charAt(resKey.length)) - { - var attrKey = key.substring(resKey.length + 1); - resEl[attrKey] = resValue; - } - } - } - } - } - return resourceBundle; -}; - -/** - * Writes installation information to a file. - * - * @return The file path. - */ -CSInterface.prototype.dumpInstallationInfo = function() -{ - return window.__adobe_cep__.dumpInstallationInfo(); -}; - -/** - * Retrieves version information for the current Operating System, - * See http://www.useragentstring.com/pages/Chrome/ for Chrome \c navigator.userAgent values. - * - * @return A string containing the OS version, or "unknown Operation System". - * If user customizes the User Agent by setting CEF command parameter "--user-agent", only - * "Mac OS X" or "Windows" will be returned. - */ -CSInterface.prototype.getOSInformation = function() -{ - var userAgent = navigator.userAgent; - - if ((navigator.platform == "Win32") || (navigator.platform == "Windows")) - { - var winVersion = "Windows"; - var winBit = ""; - if (userAgent.indexOf("Windows") > -1) - { - if (userAgent.indexOf("Windows NT 5.0") > -1) - { - winVersion = "Windows 2000"; - } - else if (userAgent.indexOf("Windows NT 5.1") > -1) - { - winVersion = "Windows XP"; - } - else if (userAgent.indexOf("Windows NT 5.2") > -1) - { - winVersion = "Windows Server 2003"; - } - else if (userAgent.indexOf("Windows NT 6.0") > -1) - { - winVersion = "Windows Vista"; - } - else if (userAgent.indexOf("Windows NT 6.1") > -1) - { - winVersion = "Windows 7"; - } - else if (userAgent.indexOf("Windows NT 6.2") > -1) - { - winVersion = "Windows 8"; - } - else if (userAgent.indexOf("Windows NT 6.3") > -1) - { - winVersion = "Windows 8.1"; - } - else if (userAgent.indexOf("Windows NT 10") > -1) - { - winVersion = "Windows 10"; - } - - if (userAgent.indexOf("WOW64") > -1 || userAgent.indexOf("Win64") > -1) - { - winBit = " 64-bit"; - } - else - { - winBit = " 32-bit"; - } - } - - return winVersion + winBit; - } - else if ((navigator.platform == "MacIntel") || (navigator.platform == "Macintosh")) - { - var result = "Mac OS X"; - - if (userAgent.indexOf("Mac OS X") > -1) - { - result = userAgent.substring(userAgent.indexOf("Mac OS X"), userAgent.indexOf(")")); - result = result.replace(/_/g, "."); - } - - return result; - } - - return "Unknown Operation System"; -}; - -/** - * Opens a page in the default system browser. - * - * Since 4.2.0 - * - * @param url The URL of the page/file to open, or the email address. - * Must use HTTP/HTTPS/file/mailto protocol. For example: - * "http://www.adobe.com" - * "https://github.com" - * "file:///C:/log.txt" - * "mailto:test@adobe.com" - * - * @return One of these error codes:\n - *
    \n - *
  • NO_ERROR - 0
  • \n - *
  • ERR_UNKNOWN - 1
  • \n - *
  • ERR_INVALID_PARAMS - 2
  • \n - *
  • ERR_INVALID_URL - 201
  • \n - *
\n - */ -CSInterface.prototype.openURLInDefaultBrowser = function(url) -{ - return cep.util.openURLInDefaultBrowser(url); -}; - -/** - * Retrieves extension ID. - * - * Since 4.2.0 - * - * @return extension ID. - */ -CSInterface.prototype.getExtensionID = function() -{ - return window.__adobe_cep__.getExtensionId(); -}; - -/** - * Retrieves the scale factor of screen. - * On Windows platform, the value of scale factor might be different from operating system's scale factor, - * since host application may use its self-defined scale factor. - * - * Since 4.2.0 - * - * @return One of the following float number. - *
    \n - *
  • -1.0 when error occurs
  • \n - *
  • 1.0 means normal screen
  • \n - *
  • >1.0 means HiDPI screen
  • \n - *
\n - */ -CSInterface.prototype.getScaleFactor = function() -{ - return window.__adobe_cep__.getScaleFactor(); -}; - -/** - * Retrieves the scale factor of Monitor. - * - * Since 8.5.0 - * - * @return value >= 1.0f - * only available for windows machine - */ - if(navigator.appVersion.toLowerCase().indexOf("windows") >= 0) { - CSInterface.prototype.getMonitorScaleFactor = function() - { - return window.__adobe_cep__.getMonitorScaleFactor(); - }; -} - -/** - * Set a handler to detect any changes of scale factor. This only works on Mac. - * - * Since 4.2.0 - * - * @param handler The function to be called when scale factor is changed. - * - */ -CSInterface.prototype.setScaleFactorChangedHandler = function(handler) -{ - window.__adobe_cep__.setScaleFactorChangedHandler(handler); -}; - -/** - * Retrieves current API version. - * - * Since 4.2.0 - * - * @return ApiVersion object. - * - */ -CSInterface.prototype.getCurrentApiVersion = function() -{ - var apiVersion = JSON.parse(window.__adobe_cep__.getCurrentApiVersion()); - return apiVersion; -}; - -/** - * Set panel flyout menu by an XML. - * - * Since 5.2.0 - * - * Register a callback function for "com.adobe.csxs.events.flyoutMenuClicked" to get notified when a - * menu item is clicked. - * The "data" attribute of event is an object which contains "menuId" and "menuName" attributes. - * - * Register callback functions for "com.adobe.csxs.events.flyoutMenuOpened" and "com.adobe.csxs.events.flyoutMenuClosed" - * respectively to get notified when flyout menu is opened or closed. - * - * @param menu A XML string which describes menu structure. - * An example menu XML: - * - * - * - * - * - * - * - * - * - * - * - * - */ -CSInterface.prototype.setPanelFlyoutMenu = function(menu) -{ - if ("string" != typeof menu) - { - return; - } - - window.__adobe_cep__.invokeSync("setPanelFlyoutMenu", menu); -}; - -/** - * Updates a menu item in the extension window's flyout menu, by setting the enabled - * and selection status. - * - * Since 5.2.0 - * - * @param menuItemLabel The menu item label. - * @param enabled True to enable the item, false to disable it (gray it out). - * @param checked True to select the item, false to deselect it. - * - * @return false when the host application does not support this functionality (HostCapabilities.EXTENDED_PANEL_MENU is false). - * Fails silently if menu label is invalid. - * - * @see HostCapabilities.EXTENDED_PANEL_MENU - */ -CSInterface.prototype.updatePanelMenuItem = function(menuItemLabel, enabled, checked) -{ - var ret = false; - if (this.getHostCapabilities().EXTENDED_PANEL_MENU) - { - var itemStatus = new MenuItemStatus(menuItemLabel, enabled, checked); - ret = window.__adobe_cep__.invokeSync("updatePanelMenuItem", JSON.stringify(itemStatus)); - } - return ret; -}; - - -/** - * Set context menu by XML string. - * - * Since 5.2.0 - * - * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. - * - an item without menu ID or menu name is disabled and is not shown. - * - if the item name is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. - * - Checkable attribute takes precedence over Checked attribute. - * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. - The Chrome extension contextMenus API was taken as a reference. - https://developer.chrome.com/extensions/contextMenus - * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. - * - * @param menu A XML string which describes menu structure. - * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. - * - * @description An example menu XML: - * - * - * - * - * - * - * - * - * - * - * - */ -CSInterface.prototype.setContextMenu = function(menu, callback) -{ - if ("string" != typeof menu) - { - return; - } - - window.__adobe_cep__.invokeAsync("setContextMenu", menu, callback); -}; - -/** - * Set context menu by JSON string. - * - * Since 6.0.0 - * - * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. - * - an item without menu ID or menu name is disabled and is not shown. - * - if the item label is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. - * - Checkable attribute takes precedence over Checked attribute. - * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. - The Chrome extension contextMenus API was taken as a reference. - * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. - https://developer.chrome.com/extensions/contextMenus - * - * @param menu A JSON string which describes menu structure. - * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. - * - * @description An example menu JSON: - * - * { - * "menu": [ - * { - * "id": "menuItemId1", - * "label": "testExample1", - * "enabled": true, - * "checkable": true, - * "checked": false, - * "icon": "./image/small_16X16.png" - * }, - * { - * "id": "menuItemId2", - * "label": "testExample2", - * "menu": [ - * { - * "id": "menuItemId2-1", - * "label": "testExample2-1", - * "menu": [ - * { - * "id": "menuItemId2-1-1", - * "label": "testExample2-1-1", - * "enabled": false, - * "checkable": true, - * "checked": true - * } - * ] - * }, - * { - * "id": "menuItemId2-2", - * "label": "testExample2-2", - * "enabled": true, - * "checkable": true, - * "checked": true - * } - * ] - * }, - * { - * "label": "---" - * }, - * { - * "id": "menuItemId3", - * "label": "testExample3", - * "enabled": false, - * "checkable": true, - * "checked": false - * } - * ] - * } - * - */ -CSInterface.prototype.setContextMenuByJSON = function(menu, callback) -{ - if ("string" != typeof menu) - { - return; - } - - window.__adobe_cep__.invokeAsync("setContextMenuByJSON", menu, callback); -}; - -/** - * Updates a context menu item by setting the enabled and selection status. - * - * Since 5.2.0 - * - * @param menuItemID The menu item ID. - * @param enabled True to enable the item, false to disable it (gray it out). - * @param checked True to select the item, false to deselect it. - */ -CSInterface.prototype.updateContextMenuItem = function(menuItemID, enabled, checked) -{ - var itemStatus = new ContextMenuItemStatus(menuItemID, enabled, checked); - ret = window.__adobe_cep__.invokeSync("updateContextMenuItem", JSON.stringify(itemStatus)); -}; - -/** - * Get the visibility status of an extension window. - * - * Since 6.0.0 - * - * @return true if the extension window is visible; false if the extension window is hidden. - */ -CSInterface.prototype.isWindowVisible = function() -{ - return window.__adobe_cep__.invokeSync("isWindowVisible", ""); -}; - -/** - * Resize extension's content to the specified dimensions. - * 1. Works with modal and modeless extensions in all Adobe products. - * 2. Extension's manifest min/max size constraints apply and take precedence. - * 3. For panel extensions - * 3.1 This works in all Adobe products except: - * * Premiere Pro - * * Prelude - * * After Effects - * 3.2 When the panel is in certain states (especially when being docked), - * it will not change to the desired dimensions even when the - * specified size satisfies min/max constraints. - * - * Since 6.0.0 - * - * @param width The new width - * @param height The new height - */ -CSInterface.prototype.resizeContent = function(width, height) -{ - window.__adobe_cep__.resizeContent(width, height); -}; - -/** - * Register the invalid certificate callback for an extension. - * This callback will be triggered when the extension tries to access the web site that contains the invalid certificate on the main frame. - * But if the extension does not call this function and tries to access the web site containing the invalid certificate, a default error page will be shown. - * - * Since 6.1.0 - * - * @param callback the callback function - */ -CSInterface.prototype.registerInvalidCertificateCallback = function(callback) -{ - return window.__adobe_cep__.registerInvalidCertificateCallback(callback); -}; - -/** - * Register an interest in some key events to prevent them from being sent to the host application. - * - * This function works with modeless extensions and panel extensions. - * Generally all the key events will be sent to the host application for these two extensions if the current focused element - * is not text input or dropdown, - * If you want to intercept some key events and want them to be handled in the extension, please call this function - * in advance to prevent them being sent to the host application. - * - * Since 6.1.0 - * - * @param keyEventsInterest A JSON string describing those key events you are interested in. A null object or - an empty string will lead to removing the interest - * - * This JSON string should be an array, each object has following keys: - * - * keyCode: [Required] represents an OS system dependent virtual key code identifying - * the unmodified value of the pressed key. - * ctrlKey: [optional] a Boolean that indicates if the control key was pressed (true) or not (false) when the event occurred. - * altKey: [optional] a Boolean that indicates if the alt key was pressed (true) or not (false) when the event occurred. - * shiftKey: [optional] a Boolean that indicates if the shift key was pressed (true) or not (false) when the event occurred. - * metaKey: [optional] (Mac Only) a Boolean that indicates if the Meta key was pressed (true) or not (false) when the event occurred. - * On Macintosh keyboards, this is the command key. To detect Windows key on Windows, please use keyCode instead. - * An example JSON string: - * - * [ - * { - * "keyCode": 48 - * }, - * { - * "keyCode": 123, - * "ctrlKey": true - * }, - * { - * "keyCode": 123, - * "ctrlKey": true, - * "metaKey": true - * } - * ] - * - */ -CSInterface.prototype.registerKeyEventsInterest = function(keyEventsInterest) -{ - return window.__adobe_cep__.registerKeyEventsInterest(keyEventsInterest); -}; - -/** - * Set the title of the extension window. - * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. - * - * Since 6.1.0 - * - * @param title The window title. - */ -CSInterface.prototype.setWindowTitle = function(title) -{ - window.__adobe_cep__.invokeSync("setWindowTitle", title); -}; - -/** - * Get the title of the extension window. - * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. - * - * Since 6.1.0 - * - * @return The window title. - */ -CSInterface.prototype.getWindowTitle = function() -{ - return window.__adobe_cep__.invokeSync("getWindowTitle", ""); -}; diff --git a/pype/hosts/premiere/extensions/com.pype.rename/lib/Vulcan.js b/pype/hosts/premiere/extensions/com.pype.rename/lib/Vulcan.js deleted file mode 100644 index 10db662fd3..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/lib/Vulcan.js +++ /dev/null @@ -1,459 +0,0 @@ -/************************************************************************************************** -* -* ADOBE SYSTEMS INCORPORATED -* Copyright 2013 Adobe Systems Incorporated -* All Rights Reserved. -* -* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the -* terms of the Adobe license agreement accompanying it. If you have received this file from a -* source other than Adobe, then your use, modification, or distribution of it requires the prior -* written permission of Adobe. -* -**************************************************************************************************/ - -/** Vulcan - v9.2.0 */ - -/** - * @class Vulcan - * - * The singleton instance, VulcanInterface, provides an interface - * to the Vulcan. Allows you to launch CC applications - * and discover information about them. - */ -function Vulcan() -{ -} - -/** - * Gets all available application specifiers on the local machine. - * - * @return The array of all available application specifiers. - */ -Vulcan.prototype.getTargetSpecifiers = function() -{ - var params = {}; - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetTargetSpecifiers", JSON.stringify(params))); -}; - -/** - * Launches a CC application on the local machine, if it is not already running. - * - * @param targetSpecifier The application specifier; for example "indesign". - * - * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version - * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you - * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may - * receive wrong result. - * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". - * - * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. - * @param focus True to launch in foreground, or false to launch in the background. - * @param cmdLine Optional, command-line parameters to supply to the launch command. - * @return True if the app can be launched, false otherwise. - */ -Vulcan.prototype.launchApp = function(targetSpecifier, focus, cmdLine) -{ - if(!requiredParamsValid(targetSpecifier)) - { - return false; - } - - var params = {}; - params.targetSpecifier = targetSpecifier; - params.focus = focus ? "true" : "false"; - params.cmdLine = requiredParamsValid(cmdLine) ? cmdLine : ""; - - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanLaunchApp", JSON.stringify(params))).result; -}; - -/** - * Checks whether a CC application is running on the local machine. - * - * @param targetSpecifier The application specifier; for example "indesign". - * - * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version - * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you - * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may - * receive wrong result. - * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". - * - * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. - * @return True if the app is running, false otherwise. - */ -Vulcan.prototype.isAppRunning = function(targetSpecifier) -{ - if(!requiredParamsValid(targetSpecifier)) - { - return false; - } - - var params = {}; - params.targetSpecifier = targetSpecifier; - - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanIsAppRunning", JSON.stringify(params))).result; -}; - -/** - * Checks whether a CC application is installed on the local machine. - * - * @param targetSpecifier The application specifier; for example "indesign". - * - * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version - * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you - * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may - * receive wrong result. - * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". - * - * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. - * @return True if the app is installed, false otherwise. - */ -Vulcan.prototype.isAppInstalled = function(targetSpecifier) -{ - if(!requiredParamsValid(targetSpecifier)) - { - return false; - } - - var params = {}; - params.targetSpecifier = targetSpecifier; - - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanIsAppInstalled", JSON.stringify(params))).result; -}; - -/** - * Retrieves the local install path of a CC application. - * - * @param targetSpecifier The application specifier; for example "indesign". - * - * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version - * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you - * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may - * receive wrong result. - * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". - * - * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. - * @return The path string if the application is found, "" otherwise. - */ -Vulcan.prototype.getAppPath = function(targetSpecifier) -{ - if(!requiredParamsValid(targetSpecifier)) - { - return ""; - } - - var params = {}; - params.targetSpecifier = targetSpecifier; - - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetAppPath", JSON.stringify(params))).result; -}; - -/** - * Registers a message listener callback function for a Vulcan message. - * - * @param type The message type. - * @param callback The callback function that handles the message. - * Takes one argument, the message object. - * @param obj Optional, the object containing the callback method, if any. - * Default is null. - */ -Vulcan.prototype.addMessageListener = function(type, callback, obj) -{ - if(!requiredParamsValid(type, callback) || !strStartsWith(type, VulcanMessage.TYPE_PREFIX)) - { - return; - } - - var params = {}; - params.type = type; - - window.__adobe_cep__.invokeAsync("vulcanAddMessageListener", JSON.stringify(params), callback, obj); -}; - -/** - * Removes a registered message listener callback function for a Vulcan message. - * - * @param type The message type. - * @param callback The callback function that was registered. - * Takes one argument, the message object. - * @param obj Optional, the object containing the callback method, if any. - * Default is null. - */ -Vulcan.prototype.removeMessageListener = function(type, callback, obj) -{ - if(!requiredParamsValid(type, callback) || !strStartsWith(type, VulcanMessage.TYPE_PREFIX)) - { - return; - } - - var params = {}; - params.type = type; - - window.__adobe_cep__.invokeAsync("vulcanRemoveMessageListener", JSON.stringify(params), callback, obj); -}; - -/** - * Dispatches a Vulcan message. - * - * @param vulcanMessage The message object. - */ -Vulcan.prototype.dispatchMessage = function(vulcanMessage) -{ - if(!requiredParamsValid(vulcanMessage) || !strStartsWith(vulcanMessage.type, VulcanMessage.TYPE_PREFIX)) - { - return; - } - - var params = {}; - var message = new VulcanMessage(vulcanMessage.type); - message.initialize(vulcanMessage); - params.vulcanMessage = message; - - window.__adobe_cep__.invokeSync("vulcanDispatchMessage", JSON.stringify(params)); -}; - -/** - * Retrieves the message payload of a Vulcan message for the registered message listener callback function. - * - * @param vulcanMessage The message object. - * @return A string containing the message payload. - */ -Vulcan.prototype.getPayload = function(vulcanMessage) -{ - if(!requiredParamsValid(vulcanMessage) || !strStartsWith(vulcanMessage.type, VulcanMessage.TYPE_PREFIX)) - { - return null; - } - - var message = new VulcanMessage(vulcanMessage.type); - message.initialize(vulcanMessage); - return message.getPayload(); -}; - -/** - * Gets all available endpoints of the running Vulcan-enabled applications. - * - * Since 7.0.0 - * - * @return The array of all available endpoints. - * An example endpoint string: - * - * PHXS - * 16.1.0 - * - */ -Vulcan.prototype.getEndPoints = function() -{ - var params = {}; - return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetEndPoints", JSON.stringify(params))); -}; - -/** - * Gets the endpoint for itself. - * - * Since 7.0.0 - * - * @return The endpoint string for itself. - */ -Vulcan.prototype.getSelfEndPoint = function() -{ - var params = {}; - return window.__adobe_cep__.invokeSync("vulcanGetSelfEndPoint", JSON.stringify(params)); -}; - -/** Singleton instance of Vulcan **/ -var VulcanInterface = new Vulcan(); - -//--------------------------------- Vulcan Message ------------------------------ - -/** - * @class VulcanMessage - * Message type for sending messages between host applications. - * A message of this type can be sent to the designated destination - * when appId and appVersion are provided and valid. Otherwise, - * the message is broadcast to all running Vulcan-enabled applications. - * - * To send a message between extensions running within one - * application, use the CSEvent type in CSInterface.js. - * - * @param type The message type. - * @param appId The peer appId. - * @param appVersion The peer appVersion. - * - */ -function VulcanMessage(type, appId, appVersion) -{ - this.type = type; - this.scope = VulcanMessage.SCOPE_SUITE; - this.appId = requiredParamsValid(appId) ? appId : VulcanMessage.DEFAULT_APP_ID; - this.appVersion = requiredParamsValid(appVersion) ? appVersion : VulcanMessage.DEFAULT_APP_VERSION; - this.data = VulcanMessage.DEFAULT_DATA; -} - -VulcanMessage.TYPE_PREFIX = "vulcan.SuiteMessage."; -VulcanMessage.SCOPE_SUITE = "GLOBAL"; -VulcanMessage.DEFAULT_APP_ID = "UNKNOWN"; -VulcanMessage.DEFAULT_APP_VERSION = "UNKNOWN"; -VulcanMessage.DEFAULT_DATA = ""; -VulcanMessage.dataTemplate = "{0}"; -VulcanMessage.payloadTemplate = "{0}"; - -/** - * Initializes this message instance. - * - * @param message A \c message instance to use for initialization. - */ -VulcanMessage.prototype.initialize = function(message) -{ - this.type = message.type; - this.scope = message.scope; - this.appId = message.appId; - this.appVersion = message.appVersion; - this.data = message.data; -}; - -/** - * Retrieves the message data. - * - * @return A data string in XML format. - */ -VulcanMessage.prototype.xmlData = function() -{ - if(this.data === undefined) - { - var str = ""; - str = String.format(VulcanMessage.payloadTemplate, str); - this.data = String.format(VulcanMessage.dataTemplate, str); - } - return this.data; -}; - -/** - * Sets the message payload of this message. - * - * @param payload A string containing the message payload. - */ -VulcanMessage.prototype.setPayload = function(payload) -{ - var str = cep.encoding.convertion.utf8_to_b64(payload); - str = String.format(VulcanMessage.payloadTemplate, str); - this.data = String.format(VulcanMessage.dataTemplate, str); -}; - -/** - * Retrieves the message payload of this message. - * - * @return A string containing the message payload. - */ -VulcanMessage.prototype.getPayload = function() -{ - var str = GetValueByKey(this.data, "payload"); - if(str !== null) - { - return cep.encoding.convertion.b64_to_utf8(str); - } - return null; -}; - -/** - * Converts the properties of this instance to a string. - * - * @return The string version of this instance. - */ -VulcanMessage.prototype.toString = function() -{ - var str = "type=" + this.type; - str += ", scope=" + this.scope; - str += ", appId=" + this.appId; - str += ", appVersion=" + this.appVersion; - str += ", data=" + this.xmlData(); - return str; -}; - -//--------------------------------------- Util -------------------------------- - -/** - * Formats a string based on a template. - * - * @param src The format template. - * - * @return The formatted string - */ -String.format = function(src) -{ - if (arguments.length === 0) - { - return null; - } - - var args = Array.prototype.slice.call(arguments, 1); - return src.replace(/\{(\d+)\}/g, function(m, i){ - return args[i]; - }); -}; - -/** - * Retrieves the content of an XML element. - * - * @param xmlStr The XML string. - * @param key The name of the tag. - * - * @return The content of the tag, or the empty string - * if such tag is not found or the tag has no content. - */ -function GetValueByKey(xmlStr, key) -{ - if(window.DOMParser) - { - var parser = new window.DOMParser(); - try - { - var xmlDoc = parser.parseFromString(xmlStr, "text/xml"); - var node = xmlDoc.getElementsByTagName(key)[0]; - if(node && node.childNodes[0]) - { - return node.childNodes[0].nodeValue; - } - } - catch(e) - { - //log the error - } - } - return ""; -} - -/** - * Reports whether required parameters are valid. - * - * @return True if all required parameters are valid, - * false if any of the required parameters are invalid. - */ -function requiredParamsValid() -{ - for(var i = 0; i < arguments.length; i++) - { - var argument = arguments[i]; - if(argument === undefined || argument === null) - { - return false; - } - } - return true; -} - -/** - * Reports whether a string has a given prefix. - * - * @param str The target string. - * @param prefix The specific prefix string. - * - * @return True if the string has the prefix, false if not. - */ -function strStartsWith(str, prefix) -{ - if(typeof str != "string") - { - return false; - } - return str.indexOf(prefix) === 0; -} diff --git a/pype/hosts/premiere/extensions/com.pype.rename/lib/bootstrap.min.js b/pype/hosts/premiere/extensions/com.pype.rename/lib/bootstrap.min.js deleted file mode 100644 index 9df6b6c2ce..0000000000 --- a/pype/hosts/premiere/extensions/com.pype.rename/lib/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v4.2.1 (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("popper.js"),require("jquery")):"function"==typeof define&&define.amd?define(["exports","popper.js","jquery"],e):e(t.bootstrap={},t.Popper,t.jQuery)}(this,function(t,u,g){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},De="show",we="out",Ae={HIDE:"hide"+Ee,HIDDEN:"hidden"+Ee,SHOW:"show"+Ee,SHOWN:"shown"+Ee,INSERTED:"inserted"+Ee,CLICK:"click"+Ee,FOCUSIN:"focusin"+Ee,FOCUSOUT:"focusout"+Ee,MOUSEENTER:"mouseenter"+Ee,MOUSELEAVE:"mouseleave"+Ee},Ne="fade",Oe="show",ke=".tooltip-inner",Pe=".arrow",Le="hover",je="focus",He="click",Re="manual",Ue=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Oe))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(Ne);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,{placement:a,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:Pe},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),g(o).addClass(Oe),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===we&&e._leave(null,e)};if(g(this.tip).hasClass(Ne)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=g.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==De&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),g(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(g(this.element).trigger(i),!i.isDefaultPrevented()){if(g(n).removeClass(Oe),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[He]=!1,this._activeTrigger[je]=!1,this._activeTrigger[Le]=!1,g(this.tip).hasClass(Ne)){var r=_.getTransitionDurationFromElement(n);g(n).one(_.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Ce+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(ke)),this.getTitle()),g(t).removeClass(Ne+" "+Oe)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return be[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Re){var e=t===Le?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Le?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),g(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?je:Le]=!0),g(e.getTipElement()).hasClass(Oe)||e._hoverState===De?e._hoverState=De:(clearTimeout(e._timeout),e._hoverState=De,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===De&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?je:Le]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=we,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===we&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=l({},this.constructor.Default,g(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(pe,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Te);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(Ne),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(ve),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(ve,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.2.1"}},{key:"Default",get:function(){return Ie}},{key:"NAME",get:function(){return pe}},{key:"DATA_KEY",get:function(){return ve}},{key:"Event",get:function(){return Ae}},{key:"EVENT_KEY",get:function(){return Ee}},{key:"DefaultType",get:function(){return Se}}]),i}();g.fn[pe]=Ue._jQueryInterface,g.fn[pe].Constructor=Ue,g.fn[pe].noConflict=function(){return g.fn[pe]=ye,Ue._jQueryInterface};var We="popover",xe="bs.popover",Fe="."+xe,qe=g.fn[We],Me="bs-popover",Ke=new RegExp("(^|\\s)"+Me+"\\S+","g"),Qe=l({},Ue.Default,{placement:"right",trigger:"click",content:"",template:''}),Be=l({},Ue.DefaultType,{content:"(string|element|function)"}),Ve="fade",Ye="show",Xe=".popover-header",ze=".popover-body",Ge={HIDE:"hide"+Fe,HIDDEN:"hidden"+Fe,SHOW:"show"+Fe,SHOWN:"shown"+Fe,INSERTED:"inserted"+Fe,CLICK:"click"+Fe,FOCUSIN:"focusin"+Fe,FOCUSOUT:"focusout"+Fe,MOUSEENTER:"mouseenter"+Fe,MOUSELEAVE:"mouseleave"+Fe},Je=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Me+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},o.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(Xe),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(ze),e),t.removeClass(Ve+" "+Ye)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ke);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n // eslint-disable-next-line no-bitwise\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n return selector && document.querySelector(selector) ? selector : null\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n // TODO: Remove in v5\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value)\n ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n }\n}\n\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Selector = {\n DISMISS : '[data-dismiss=\"alert\"]'\n}\n\nconst Event = {\n CLOSE : `close${EVENT_KEY}`,\n CLOSED : `closed${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n ALERT : 'alert',\n FADE : 'fade',\n SHOW : 'show'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${ClassName.ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(Event.CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(ClassName.SHOW)\n\n if (!$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(Event.CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n Event.CLICK_DATA_API,\n Selector.DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst ClassName = {\n ACTIVE : 'active',\n BUTTON : 'btn',\n FOCUS : 'focus'\n}\n\nconst Selector = {\n DATA_TOGGLE_CARROT : '[data-toggle^=\"button\"]',\n DATA_TOGGLE : '[data-toggle=\"buttons\"]',\n INPUT : 'input:not([type=\"hidden\"])',\n ACTIVE : '.active',\n BUTTON : '.btn'\n}\n\nconst Event = {\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(\n Selector.DATA_TOGGLE\n )[0]\n\n if (rootElement) {\n const input = this._element.querySelector(Selector.INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked &&\n this._element.classList.contains(ClassName.ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(Selector.ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(ClassName.ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n if (input.hasAttribute('disabled') ||\n rootElement.hasAttribute('disabled') ||\n input.classList.contains('disabled') ||\n rootElement.classList.contains('disabled')) {\n return\n }\n input.checked = !this._element.classList.contains(ClassName.ACTIVE)\n $(input).trigger('change')\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed',\n !this._element.classList.contains(ClassName.ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(ClassName.ACTIVE)\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $(this).data(DATA_KEY, data)\n }\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n event.preventDefault()\n\n let button = event.target\n\n if (!$(button).hasClass(ClassName.BUTTON)) {\n button = $(button).closest(Selector.BUTTON)\n }\n\n Button._jQueryInterface.call($(button), 'toggle')\n })\n .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n const button = $(event.target).closest(Selector.BUTTON)[0]\n $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval : 5000,\n keyboard : true,\n slide : false,\n pause : 'hover',\n wrap : true,\n touch : true\n}\n\nconst DefaultType = {\n interval : '(number|boolean)',\n keyboard : 'boolean',\n slide : '(boolean|string)',\n pause : '(string|boolean)',\n wrap : 'boolean',\n touch : 'boolean'\n}\n\nconst Direction = {\n NEXT : 'next',\n PREV : 'prev',\n LEFT : 'left',\n RIGHT : 'right'\n}\n\nconst Event = {\n SLIDE : `slide${EVENT_KEY}`,\n SLID : `slid${EVENT_KEY}`,\n KEYDOWN : `keydown${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`,\n TOUCHSTART : `touchstart${EVENT_KEY}`,\n TOUCHMOVE : `touchmove${EVENT_KEY}`,\n TOUCHEND : `touchend${EVENT_KEY}`,\n POINTERDOWN : `pointerdown${EVENT_KEY}`,\n POINTERUP : `pointerup${EVENT_KEY}`,\n DRAG_START : `dragstart${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n CAROUSEL : 'carousel',\n ACTIVE : 'active',\n SLIDE : 'slide',\n RIGHT : 'carousel-item-right',\n LEFT : 'carousel-item-left',\n NEXT : 'carousel-item-next',\n PREV : 'carousel-item-prev',\n ITEM : 'carousel-item',\n POINTER_EVENT : 'pointer-event'\n}\n\nconst Selector = {\n ACTIVE : '.active',\n ACTIVE_ITEM : '.active.carousel-item',\n ITEM : '.carousel-item',\n ITEM_IMG : '.carousel-item img',\n NEXT_PREV : '.carousel-item-next, .carousel-item-prev',\n INDICATORS : '.carousel-indicators',\n DATA_SLIDE : '[data-slide], [data-slide-to]',\n DATA_RIDE : '[data-ride=\"carousel\"]'\n}\n\nconst PointerType = {\n TOUCH : 'touch',\n PEN : 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT)\n }\n }\n\n nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(Selector.NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(Event.SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex\n ? Direction.NEXT\n : Direction.PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element)\n .on(Event.KEYDOWN, (event) => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(Event.MOUSEENTER, (event) => this.pause(event))\n .on(Event.MOUSELEAVE, (event) => this.cycle(event))\n }\n\n this._addTouchEventListeners()\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = (event) => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = (event) => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = (event) => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(Selector.ITEM_IMG)).on(Event.DRAG_START, (e) => e.preventDefault())\n if (this._pointerEvent) {\n $(this._element).on(Event.POINTERDOWN, (event) => start(event))\n $(this._element).on(Event.POINTERUP, (event) => end(event))\n\n this._element.classList.add(ClassName.POINTER_EVENT)\n } else {\n $(this._element).on(Event.TOUCHSTART, (event) => start(event))\n $(this._element).on(Event.TOUCHMOVE, (event) => move(event))\n $(this._element).on(Event.TOUCHEND, (event) => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode\n ? [].slice.call(element.parentNode.querySelectorAll(Selector.ITEM))\n : []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === Direction.NEXT\n const isPrevDirection = direction === Direction.PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === Direction.PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1\n ? this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(Selector.ACTIVE_ITEM))\n const slideEvent = $.Event(Event.SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector.ACTIVE))\n $(indicators)\n .removeClass(ClassName.ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName.ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName.LEFT\n orderClassName = ClassName.NEXT\n eventDirectionName = Direction.LEFT\n } else {\n directionalClassName = ClassName.RIGHT\n orderClassName = ClassName.PREV\n eventDirectionName = Direction.RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(Event.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(ClassName.SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(ClassName.ACTIVE)\n\n $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(ClassName.ACTIVE)\n $(nextElement).addClass(ClassName.ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n data[action]()\n } else if (_config.interval) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(Event.LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(Selector.DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle : true,\n parent : ''\n}\n\nconst DefaultType = {\n toggle : 'boolean',\n parent : '(string|element)'\n}\n\nconst Event = {\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n SHOW : 'show',\n COLLAPSE : 'collapse',\n COLLAPSING : 'collapsing',\n COLLAPSED : 'collapsed'\n}\n\nconst Dimension = {\n WIDTH : 'width',\n HEIGHT : 'height'\n}\n\nconst Selector = {\n ACTIVES : '.show, .collapsing',\n DATA_TOGGLE : '[data-toggle=\"collapse\"]'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter((foundElem) => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(ClassName.SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))\n .filter((elem) => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(ClassName.COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(Event.SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(ClassName.COLLAPSE)\n .addClass(ClassName.COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(ClassName.COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .addClass(ClassName.SHOW)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(Event.SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n const startEvent = $.Event(Event.HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(ClassName.COLLAPSING)\n .removeClass(ClassName.COLLAPSE)\n .removeClass(ClassName.SHOW)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(ClassName.SHOW)) {\n $(trigger).addClass(ClassName.COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .trigger(Event.HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(Dimension.WIDTH)\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector =\n `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n\n const children = [].slice.call(parent.querySelectorAll(selector))\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(ClassName.SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(ClassName.COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$this.data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,\n KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n DISABLED : 'disabled',\n SHOW : 'show',\n DROPUP : 'dropup',\n DROPRIGHT : 'dropright',\n DROPLEFT : 'dropleft',\n MENURIGHT : 'dropdown-menu-right',\n MENULEFT : 'dropdown-menu-left',\n POSITION_STATIC : 'position-static'\n}\n\nconst Selector = {\n DATA_TOGGLE : '[data-toggle=\"dropdown\"]',\n FORM_CHILD : '.dropdown form',\n MENU : '.dropdown-menu',\n NAVBAR_NAV : '.navbar-nav',\n VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n}\n\nconst AttachmentMap = {\n TOP : 'top-start',\n TOPEND : 'top-end',\n BOTTOM : 'bottom-start',\n BOTTOMEND : 'bottom-end',\n RIGHT : 'right-start',\n RIGHTEND : 'right-end',\n LEFT : 'left-start',\n LEFTEND : 'left-end'\n}\n\nconst Default = {\n offset : 0,\n flip : true,\n boundary : 'scrollParent',\n reference : 'toggle',\n display : 'dynamic'\n}\n\nconst DefaultType = {\n offset : '(number|string|function)',\n flip : 'boolean',\n boundary : '(string|element)',\n reference : '(string|element)',\n display : 'string'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this._element)\n const isActive = $(this._menu).hasClass(ClassName.SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(Event.SHOW, relatedTarget)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(ClassName.POSITION_STATIC)\n }\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(Selector.NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.SHOWN, relatedTarget))\n }\n\n show() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || $(this._menu).hasClass(ClassName.SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(Event.SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || !$(this._menu).hasClass(ClassName.SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(Event.HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(Event.CLICK, (event) => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(Selector.MENU)\n }\n }\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = AttachmentMap.BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(ClassName.DROPUP)) {\n placement = AttachmentMap.TOP\n if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.TOPEND\n }\n } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {\n placement = AttachmentMap.RIGHT\n } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {\n placement = AttachmentMap.LEFT\n } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.BOTTOMEND\n }\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getPopperConfig() {\n const offsetConf = {}\n if (typeof this._config.offset === 'function') {\n offsetConf.fn = (data) => {\n data.offsets = {\n ...data.offsets,\n ...this._config.offset(data.offsets) || {}\n }\n return data\n }\n } else {\n offsetConf.offset = this._config.offset\n }\n\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: offsetConf,\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n return popperConfig\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(ClassName.SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(Event.HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n $(dropdownMenu).removeClass(ClassName.SHOW)\n $(parent)\n .removeClass(ClassName.SHOW)\n .trigger($.Event(Event.HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName)\n ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(ClassName.SHOW)\n\n if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n const toggle = parent.querySelector(Selector.DATA_TOGGLE)\n $(toggle).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)\n .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop : true,\n keyboard : true,\n focus : true,\n show : true\n}\n\nconst DefaultType = {\n backdrop : '(boolean|string)',\n keyboard : 'boolean',\n focus : 'boolean',\n show : 'boolean'\n}\n\nconst Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n RESIZE : `resize${EVENT_KEY}`,\n CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,\n KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,\n MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,\n MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n SCROLLBAR_MEASURER : 'modal-scrollbar-measure',\n BACKDROP : 'modal-backdrop',\n OPEN : 'modal-open',\n FADE : 'fade',\n SHOW : 'show'\n}\n\nconst Selector = {\n DIALOG : '.modal-dialog',\n DATA_TOGGLE : '[data-toggle=\"modal\"]',\n DATA_DISMISS : '[data-dismiss=\"modal\"]',\n FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT : '.sticky-top'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(Selector.DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n Event.CLICK_DISMISS,\n Selector.DATA_DISMISS,\n (event) => this.hide(event)\n )\n\n $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {\n $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(Event.HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(Event.FOCUSIN)\n\n $(this._element).removeClass(ClassName.SHOW)\n\n $(this._element).off(Event.CLICK_DISMISS)\n $(this._dialog).off(Event.MOUSEDOWN_DISMISS)\n\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, (event) => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach((htmlElement) => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `Event.CLICK_DATA_API` event that should remain\n */\n $(document).off(Event.FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.scrollTop = 0\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(ClassName.SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(Event.FOCUSIN) // Guard against infinite focus loop\n .on(Event.FOCUSIN, (event) => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {\n if (event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(Event.KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))\n } else {\n $(window).off(Event.RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(ClassName.OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(Event.HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(ClassName.FADE)\n ? ClassName.FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = ClassName.BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(Event.CLICK_DISMISS, (event) => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n if (event.target !== event.currentTarget) {\n return\n }\n if (this._config.backdrop === 'static') {\n this._element.focus()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(ClassName.SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName.SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing =\n this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(ClassName.OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = ClassName.SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY)\n ? 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(Event.SHOW, (showEvent) => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(Event.HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst DefaultType = {\n animation : 'boolean',\n template : 'string',\n title : '(string|element|function)',\n trigger : 'string',\n delay : '(number|object)',\n html : 'boolean',\n selector : '(string|boolean)',\n placement : '(string|function)',\n offset : '(number|string)',\n container : '(string|element|boolean)',\n fallbackPlacement : '(string|array)',\n boundary : '(string|element)'\n}\n\nconst AttachmentMap = {\n AUTO : 'auto',\n TOP : 'top',\n RIGHT : 'right',\n BOTTOM : 'bottom',\n LEFT : 'left'\n}\n\nconst Default = {\n animation : true,\n template : '
' +\n '
' +\n '
',\n trigger : 'hover focus',\n title : '',\n delay : 0,\n html : false,\n selector : false,\n placement : 'top',\n offset : 0,\n container : false,\n fallbackPlacement : 'flip',\n boundary : 'scrollParent'\n}\n\nconst HoverState = {\n SHOW : 'show',\n OUT : 'out'\n}\n\nconst Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n}\n\nconst ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n}\n\nconst Selector = {\n TOOLTIP : '.tooltip',\n TOOLTIP_INNER : '.tooltip-inner',\n ARROW : '.arrow'\n}\n\nconst Trigger = {\n HOVER : 'hover',\n FOCUS : 'focus',\n CLICK : 'click',\n MANUAL : 'manual'\n}\n\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal')\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(ClassName.FADE)\n }\n\n const placement = typeof this.config.placement === 'function'\n ? this.config.placement.call(this, tip, this.element)\n : this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, {\n placement: attachment,\n modifiers: {\n offset: {\n offset: this.config.offset\n },\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: Selector.ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: (data) => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: (data) => this._handlePopperPlacementChange(data)\n })\n\n $(tip).addClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HoverState.OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HoverState.SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[Trigger.CLICK] = false\n this._activeTrigger[Trigger.FOCUS] = false\n this._activeTrigger[Trigger.HOVER] = false\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n setElementContent($element, content) {\n const html = this.config.html\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n } else {\n $element[html ? 'html' : 'text'](content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function'\n ? this.config.title.call(this.element)\n : this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach((trigger) => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n (event) => this.toggle(event)\n )\n } else if (trigger !== Trigger.MANUAL) {\n const eventIn = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSEENTER\n : this.constructor.Event.FOCUSIN\n const eventOut = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSELEAVE\n : this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(\n eventIn,\n this.config.selector,\n (event) => this._enter(event)\n )\n .on(\n eventOut,\n this.config.selector,\n (event) => this._leave(event)\n )\n }\n })\n\n $(this.element).closest('.modal').on(\n 'hide.bs.modal',\n () => {\n if (this.element) {\n this.hide()\n }\n }\n )\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) {\n context._hoverState = HoverState.SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this.element).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n const popperInstance = popperData.instance\n this.tip = popperInstance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(ClassName.FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement : 'right',\n trigger : 'click',\n content : '',\n template : '
' +\n '
' +\n '

' +\n '
'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content : '(string|element|function)'\n}\n\nconst ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n}\n\nconst Selector = {\n TITLE : '.popover-header',\n CONTENT : '.popover-body'\n}\n\nconst Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(Selector.TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n this.setElementContent($tip.find(Selector.CONTENT), content)\n\n $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset : 10,\n method : 'auto',\n target : ''\n}\n\nconst DefaultType = {\n offset : 'number',\n method : 'string',\n target : '(string|element)'\n}\n\nconst Event = {\n ACTIVATE : `activate${EVENT_KEY}`,\n SCROLL : `scroll${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n DROPDOWN_ITEM : 'dropdown-item',\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active'\n}\n\nconst Selector = {\n DATA_SPY : '[data-spy=\"scroll\"]',\n ACTIVE : '.active',\n NAV_LIST_GROUP : '.nav, .list-group',\n NAV_LINKS : '.nav-link',\n NAV_ITEMS : '.nav-item',\n LIST_ITEMS : '.list-group-item',\n DROPDOWN : '.dropdown',\n DROPDOWN_ITEMS : '.dropdown-item',\n DROPDOWN_TOGGLE : '.dropdown-toggle'\n}\n\nconst OffsetMethod = {\n OFFSET : 'offset',\n POSITION : 'position'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +\n `${this._config.target} ${Selector.LIST_ITEMS},` +\n `${this._config.target} ${Selector.DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window\n ? OffsetMethod.OFFSET : OffsetMethod.POSITION\n\n const offsetMethod = this._config.method === 'auto'\n ? autoMethod : this._config.method\n\n const offsetBase = offsetMethod === OffsetMethod.POSITION\n ? this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map((element) => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n return null\n })\n .filter((item) => item)\n .sort((a, b) => a[0] - b[0])\n .forEach((item) => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.target !== 'string') {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window\n ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window\n ? window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset +\n scrollHeight -\n this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n const offsetLength = this._offsets.length\n for (let i = offsetLength; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map((selector) => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {\n $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n $link.addClass(ClassName.ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(ClassName.ACTIVE)\n // Set triggered links parents as active\n // With both
    and