diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake index b712fec7ab..dd68e379dd 100644 --- a/AutomatedTesting/Gem/Code/enabled_gems.cmake +++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake @@ -47,8 +47,7 @@ set(ENABLED_GEMS LmbrCentral LyShine HttpRequestor - Atom_AtomBridge - PythonCoverage + Atom AWSCore AWSClientAuth AWSMetrics diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py index 01974218b1..05eff871c1 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py @@ -77,7 +77,6 @@ class TestAllComponentsIndepthTests(object): unexpected_lines=unexpected_lines, halt_on_unexpected=True, cfg_args=[level], - auto_test_mode=False, null_renderer=False, ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index 26110cd954..c157c995c4 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -60,24 +60,7 @@ class TestEditMenuOptions(EditorTestHelper): ("Modify", "Transform Mode", "Rotate"), ("Modify", "Transform Mode", "Scale"), ("Editor Settings", "Global Preferences"), - ("Editor Settings", "Graphics Settings"), ("Editor Settings", "Editor Settings Manager"), - ("Editor Settings", "Graphics Performance", "PC", "Very High"), - ("Editor Settings", "Graphics Performance", "PC", "High"), - ("Editor Settings", "Graphics Performance", "PC", "Medium"), - ("Editor Settings", "Graphics Performance", "PC", "Low"), - ("Editor Settings", "Graphics Performance", "OSX Metal", "Very High"), - ("Editor Settings", "Graphics Performance", "OSX Metal", "High"), - ("Editor Settings", "Graphics Performance", "OSX Metal", "Medium"), - ("Editor Settings", "Graphics Performance", "OSX Metal", "Low"), - ("Editor Settings", "Graphics Performance", "Android", "Very High"), - ("Editor Settings", "Graphics Performance", "Android", "High"), - ("Editor Settings", "Graphics Performance", "Android", "Medium"), - ("Editor Settings", "Graphics Performance", "Android", "Low"), - ("Editor Settings", "Graphics Performance", "iOS", "Very High"), - ("Editor Settings", "Graphics Performance", "iOS", "High"), - ("Editor Settings", "Graphics Performance", "iOS", "Medium"), - ("Editor Settings", "Graphics Performance", "iOS", "Low"), ("Editor Settings", "Keyboard Customization", "Customize Keyboard"), ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"), ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"), diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py index 982f3617b5..cc5385f4ba 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py +++ b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py @@ -55,12 +55,7 @@ class TestMenus(object): "Rotate Action triggered", "Scale Action triggered", "Global Preferences Action triggered", - "Graphics Settings Action triggered", "Editor Settings Manager Action triggered", - "Very High Action triggered", - "High Action triggered", - "Medium Action triggered", - "Low Action triggered", "Customize Keyboard Action triggered", "Export Keyboard Settings Action triggered", "Import Keyboard Settings Action triggered", diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index af9fc142e2..73af69b93a 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -51,4 +51,18 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AutomatedTesting.GameLauncher AutomatedTesting.Assets ) + + ly_add_pytest( + NAME AutomatedTesting::GameLauncherWithGPU + TEST_SUITE sandbox + TEST_REQUIRES gpu + PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py + TIMEOUT 100 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::PythonBindingsExample + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + ) endif() diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt index 8a5f35fb92..13985cfb5e 100644 --- a/Code/Editor/CMakeLists.txt +++ b/Code/Editor/CMakeLists.txt @@ -111,7 +111,6 @@ ly_add_target( AZ::AzCore AZ::AzToolsFramework Gem::LmbrCentral.Static - Legacy::NewsShared AZ::AWSNativeSDKInit AZ::AtomCore Gem::Atom_RPI.Edit @@ -139,7 +138,6 @@ ly_add_source_properties( ly_add_source_properties( SOURCES Core/LevelEditorMenuHandler.cpp - GraphicsSettingsDialog.cpp MainWindow.cpp PROPERTY COMPILE_DEFINITIONS VALUES ${LY_PAL_TOOLS_DEFINES} diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp index ab1229dc6b..600691bdd6 100644 --- a/Code/Editor/Core/LevelEditorMenuHandler.cpp +++ b/Code/Editor/Core/LevelEditorMenuHandler.cpp @@ -497,9 +497,15 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe // Hide Selection editMenu.AddAction(AzToolsFramework::HideSelection); - // Unhide All + // Show All editMenu.AddAction(AzToolsFramework::ShowAll); + // Lock Selection + editMenu.AddAction(AzToolsFramework::LockSelection); + + // UnLock All + editMenu.AddAction(AzToolsFramework::UnlockAll); + /* * The following block of code is part of the feature "Isolation Mode" and is temporarily * disabled for 1.10 release. @@ -552,49 +558,9 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe // Global Preferences... editorSettingsMenu.AddAction(ID_TOOLS_PREFERENCES); - // Graphics Settings... - editorSettingsMenu.AddAction(ID_GRAPHICS_SETTINGS); - // Editor Settings Manager AddOpenViewPaneAction(editorSettingsMenu, LyViewPane::EditorSettingsManager); - // Graphics Performance - auto graphicPerformanceSubMenu = editorSettingsMenu.AddMenu(QObject::tr("Graphics Performance")); - - auto pcMenu = graphicPerformanceSubMenu.AddMenu(tr("PC")); - pcMenu.AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC); - pcMenu.AddAction(ID_GAME_PC_ENABLEHIGHSPEC); - pcMenu.AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC); - pcMenu.AddAction(ID_GAME_PC_ENABLELOWSPEC); - - auto osxmetalMenu = graphicPerformanceSubMenu.AddMenu(tr("OSX Metal")); - osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC); - osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC); - osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC); - osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC); - - auto androidMenu = graphicPerformanceSubMenu.AddMenu(tr("Android")); - androidMenu.AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC); - androidMenu.AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC); - androidMenu.AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC); - androidMenu.AddAction(ID_GAME_ANDROID_ENABLELOWSPEC); - - auto iosMenu = graphicPerformanceSubMenu.AddMenu(tr("iOS")); - iosMenu.AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC); - iosMenu.AddAction(ID_GAME_IOS_ENABLEHIGHSPEC); - iosMenu.AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC); - iosMenu.AddAction(ID_GAME_IOS_ENABLELOWSPEC); - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - auto publicname##Menu = graphicPerformanceSubMenu.AddMenu(tr(PublicAuxName2));\ - publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEHIGHSPEC);\ - publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC);\ - publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLELOWSPEC); - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - // Keyboard Customization auto keyboardCustomizationMenu = editorSettingsMenu.AddMenu(tr("Keyboard Customization")); keyboardCustomizationMenu.AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD); diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 8efd4bc5b3..b0dddc94ae 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -111,7 +111,6 @@ AZ_POP_DISABLE_WARNING #include "ToolBox.h" #include "LevelInfo.h" #include "EditorPreferencesDialog.h" -#include "GraphicsSettingsDialog.h" #include "AnimationContext.h" #include "GotoPositionDlg.h" @@ -440,7 +439,6 @@ void CCryEditApp::RegisterActionHandlers() ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData) ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel) ON_COMMAND(ID_TOOLS_PREFERENCES, OnToolsPreferences) - ON_COMMAND(ID_GRAPHICS_SETTINGS, OnGraphicsSettings) ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchToDefaultCamera) ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchToSequenceCamera) ON_COMMAND(ID_SWITCHCAMERA_SELECTEDCAMERA, OnSwitchToSelectedcamera) @@ -453,14 +451,6 @@ void CCryEditApp::RegisterActionHandlers() ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView) ON_COMMAND(ID_OPEN_UICANVASEDITOR, OnOpenUICanvasEditor) - ON_COMMAND_RANGE(ID_GAME_PC_ENABLELOWSPEC, ID_GAME_PC_ENABLEVERYHIGHSPEC, OnChangeGameSpec) - - ON_COMMAND_RANGE(ID_GAME_OSXMETAL_ENABLELOWSPEC, ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, OnChangeGameSpec) - - ON_COMMAND_RANGE(ID_GAME_ANDROID_ENABLELOWSPEC, ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, OnChangeGameSpec) - - ON_COMMAND_RANGE(ID_GAME_IOS_ENABLELOWSPEC, ID_GAME_IOS_ENABLEVERYHIGHSPEC, OnChangeGameSpec) - #if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ ON_COMMAND_RANGE(ID_GAME_##CODENAME##_ENABLELOWSPEC, ID_GAME_##CODENAME##_ENABLEHIGHSPEC, OnChangeGameSpec) @@ -3674,13 +3664,6 @@ void CCryEditApp::OnToolsPreferences() dlg.exec(); } -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnGraphicsSettings() -{ - GraphicsSettingsDialog dlg(MainWindow::instance()); - dlg.exec(); -} - ////////////////////////////////////////////////////////////////////////// void CCryEditApp::OnSwitchToDefaultCamera() { @@ -3815,91 +3798,6 @@ void CCryEditApp::OnOpenUICanvasEditor() QtViewPaneManager::instance()->OpenPane(LyViewPane::UiEditor); } -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable) -{ - if (GetIEditor()->GetEditorConfigSpec() == spec && GetIEditor()->GetEditorConfigPlatform() == platform) - { - nCheck = 1; - } - enable = spec <= GetIEditor()->GetSystem()->GetMaxConfigSpec(); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnUpdateGameSpec(QAction* action) -{ - Q_ASSERT(action->isCheckable()); - int nCheck = 0; - bool enable = true; - switch (action->data().toInt()) - { - case ID_GAME_PC_ENABLELOWSPEC: - SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_PC, nCheck, enable); - break; - case ID_GAME_PC_ENABLEMEDIUMSPEC: - SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_PC, nCheck, enable); - break; - case ID_GAME_PC_ENABLEHIGHSPEC: - SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_PC, nCheck, enable); - break; - case ID_GAME_PC_ENABLEVERYHIGHSPEC: - SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_PC, nCheck, enable); - break; - case ID_GAME_OSXMETAL_ENABLELOWSPEC: - SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_OSX_METAL, nCheck, enable); - break; - case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC: - SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL, nCheck, enable); - break; - case ID_GAME_OSXMETAL_ENABLEHIGHSPEC: - SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable); - break; - case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC: - SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable); - break; - case ID_GAME_ANDROID_ENABLELOWSPEC: - SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_ANDROID, nCheck, enable); - break; - case ID_GAME_ANDROID_ENABLEMEDIUMSPEC: - SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID, nCheck, enable); - break; - case ID_GAME_ANDROID_ENABLEHIGHSPEC: - SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_ANDROID, nCheck, enable); - break; - case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC: - SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID, nCheck, enable); - break; - case ID_GAME_IOS_ENABLELOWSPEC: - SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_IOS, nCheck, enable); - break; - case ID_GAME_IOS_ENABLEMEDIUMSPEC: - SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_IOS, nCheck, enable); - break; - case ID_GAME_IOS_ENABLEHIGHSPEC: - SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_IOS, nCheck, enable); - break; - case ID_GAME_IOS_ENABLEVERYHIGHSPEC: - SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_IOS, nCheck, enable); - break; -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - case ID_GAME_##CODENAME##_ENABLELOWSPEC:\ - SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_##CODENAME, nCheck, enable);\ - break;\ - case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\ - SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME, nCheck, enable);\ - break;\ - case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\ - SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_##CODENAME, nCheck, enable);\ - break; - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - } - action->setChecked(nCheck); - action->setEnabled(enable); -} - ////////////////////////////////////////////////////////////////////////// RecentFileList* CCryEditApp::GetRecentFileList() { diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h index 0628289897..5de8aa5e6c 100644 --- a/Code/Editor/CryEdit.h +++ b/Code/Editor/CryEdit.h @@ -403,7 +403,6 @@ private: void OnClearRegistryData(); void OnValidatelevel(); void OnToolsPreferences(); - void OnGraphicsSettings(); void OnSwitchToDefaultCamera(); void OnUpdateSwitchToDefaultCamera(QAction* action); void OnSwitchToSequenceCamera(); @@ -416,9 +415,6 @@ private: void OnOpenTrackView(); void OnOpenAudioControlsEditor(); void OnOpenUICanvasEditor(); - void OnChangeGameSpec(UINT nID); - void SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable); - void OnUpdateGameSpec(QAction* action); void OnOpenQuickAccessBar(); public: diff --git a/Code/Editor/CryEditPy.cpp b/Code/Editor/CryEditPy.cpp index 02833a84e0..2e414da277 100644 --- a/Code/Editor/CryEditPy.cpp +++ b/Code/Editor/CryEditPy.cpp @@ -407,78 +407,6 @@ inline namespace Commands } } -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnChangeGameSpec(UINT nID) -{ - switch (nID) - { - case ID_GAME_PC_ENABLELOWSPEC: - Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_PC); - break; - case ID_GAME_PC_ENABLEMEDIUMSPEC: - Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_PC); - break; - case ID_GAME_PC_ENABLEHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_PC); - break; - case ID_GAME_PC_ENABLEVERYHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_PC); - break; - case ID_GAME_OSXMETAL_ENABLELOWSPEC: - Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_OSX_METAL); - break; - case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC: - Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL); - break; - case ID_GAME_OSXMETAL_ENABLEHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL); - break; - case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL); - break; - case ID_GAME_ANDROID_ENABLELOWSPEC: - Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_ANDROID); - break; - case ID_GAME_ANDROID_ENABLEMEDIUMSPEC: - Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID); - break; - case ID_GAME_ANDROID_ENABLEHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_ANDROID); - break; - case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID); - break; - case ID_GAME_IOS_ENABLELOWSPEC: - Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_IOS); - break; - case ID_GAME_IOS_ENABLEMEDIUMSPEC: - Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_IOS); - break; - case ID_GAME_IOS_ENABLEHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_IOS); - break; - case ID_GAME_IOS_ENABLEVERYHIGHSPEC: - Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_IOS); - break; -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - case ID_GAME_##CODENAME##_ENABLELOWSPEC:\ - Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_##CODENAME);\ - break;\ - case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\ - Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME);\ - break;\ - case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\ - Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_##CODENAME);\ - break; - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - } -} - - - namespace AzToolsFramework { void CryEditPythonHandler::Reflect(AZ::ReflectContext* context) diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 36dc30e1d5..3f86260f8d 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -458,25 +458,7 @@ void EditorViewportWidget::Update() SetFOV(cameraState.m_fovOrZoom); m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip); } - else if (!ed_useNewCameraSystem) - { - m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix())); - } - // Don't override the game mode FOV - if (!GetIEditor()->IsInGameMode()) - { - AZ::Matrix4x4 clipMatrix; - AZ::MakePerspectiveFovMatrixRH( - clipMatrix, - GetFOV(), - aznumeric_cast(width()) / aznumeric_cast(height()), - m_Camera.GetNearPlane(), - m_Camera.GetFarPlane(), - true - ); - m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix); - } // Reset the camera update flag now that we're finished updating our viewport context m_updateCameraPositionNextTick = false; @@ -632,7 +614,6 @@ void EditorViewportWidget::SetViewEntity(const AZ::EntityId& viewEntityId, bool void EditorViewportWidget::ResetToViewSourceType(const ViewSourceType& viewSourceType) { LockCameraMovement(true); - m_pCameraFOVVariable = nullptr; m_viewEntityId.SetInvalid(); m_cameraObjectId = GUID_NULL; m_viewSourceType = viewSourceType; @@ -2547,13 +2528,26 @@ void EditorViewportWidget::CenterOnSliceInstance() ////////////////////////////////////////////////////////////////////////// void EditorViewportWidget::SetFOV(float fov) { - if (m_pCameraFOVVariable) + if (m_viewEntityId.IsValid()) { - m_pCameraFOVVariable->Set(fov); + Camera::CameraRequestBus::Event(m_viewEntityId, &Camera::CameraComponentRequests::SetFov, AZ::RadToDeg(fov)); } else { m_camFOV = fov; + // Set the active camera's FOV + { + AZ::Matrix4x4 clipMatrix; + AZ::MakePerspectiveFovMatrixRH( + clipMatrix, + GetFOV(), + aznumeric_cast(width()) / aznumeric_cast(height()), + m_Camera.GetNearPlane(), + m_Camera.GetFarPlane(), + true + ); + m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix); + } } if (m_viewPane) @@ -2580,13 +2574,7 @@ float EditorViewportWidget::GetFOV() const } } - if (m_pCameraFOVVariable) - { - float fov; - m_pCameraFOVVariable->Get(fov); - return fov; - } - else if (m_viewEntityId.IsValid()) + if (m_viewEntityId.IsValid()) { float fov = AZ::RadToDeg(m_camFOV); Camera::CameraRequestBus::EventResult(fov, m_viewEntityId, &Camera::CameraComponentRequests::GetFov); diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h index a395ef50a4..69015dcc79 100644 --- a/Code/Editor/EditorViewportWidget.h +++ b/Code/Editor/EditorViewportWidget.h @@ -506,7 +506,6 @@ protected: CPredefinedAspectRatios m_predefinedAspectRatios; - IVariable* m_pCameraFOVVariable = nullptr; bool m_bCursorHidden = false; void OnMenuResolutionCustom(); diff --git a/Code/Editor/GraphicsSettingsDialog.cpp b/Code/Editor/GraphicsSettingsDialog.cpp deleted file mode 100644 index dbd7a7fc1a..0000000000 --- a/Code/Editor/GraphicsSettingsDialog.cpp +++ /dev/null @@ -1,1392 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#include -#include -#include -#include "ProjectDefines.h" -#include "EditorDefs.h" - -#include "GraphicsSettingsDialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// AzFramework -#include -#include -#include -#include - -// Editor -#include "Util/AutoDirectoryRestoreFileDialog.h" - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include "ui_graphicssettingsdialog.h" -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - -QString groupNames[] = -{ - "Game Effects", - "Light", - "Object Detail", - "Particles", - "Physics", - "Post Processing", - "Quality", - "Shading", - "Shadows", - "Sound", - "Texture", - "Texture Resolution", - "Volumetric Effects", - "Water", - "Miscellaneous" -}; - -GraphicsSettingsDialog::GraphicsSettingsDialog(QWidget* parent /* = nullptr */) - : QDialog(parent) - , m_ui(new Ui::GraphicsSettingsDialog()) -{ - //Update qlabel color when disabled - setStyleSheet("QLabel::disabled{color: gray;}"); - - // Start initialization the dialog - m_ui->setupUi(this); - setWindowTitle("Graphics Settings"); - m_ui->m_applyButton->setDefault(true); - m_headerView = new GraphicsSettingsHeaderView(this, Qt::Horizontal); - m_headerView->setMouseTracking(true); - m_ui->m_graphicsSettingsTreeView->setHeader(m_headerView); - ///////////////////////////////////////////// - - m_currentPlatform = GetISystem()->GetConfigPlatform(); - m_currentSpecIndex = 0; - m_dirtyCVarCount = 0; - - m_showCustomSpec = true; - ShowCustomSpecOption(false); - - // Show categories, disable apply button - m_showCategories = true; - m_ui->m_applyButton->setEnabled(false); - - m_graphicsSettingsModel = new GraphicsSettingsModel(this); - m_ui->m_graphicsSettingsTreeView->setModel(m_graphicsSettingsModel); - - m_cfgFiles[CONFIG_PC].push_back("pc_low.cfg"); - m_cfgFiles[CONFIG_PC].push_back("pc_medium.cfg"); - m_cfgFiles[CONFIG_PC].push_back("pc_high.cfg"); - m_cfgFiles[CONFIG_PC].push_back("pc_veryhigh.cfg"); - m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_low.cfg"); - m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_medium.cfg"); - m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_high.cfg"); - m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_veryhigh.cfg"); - m_cfgFiles[CONFIG_ANDROID].push_back("android_low.cfg"); - m_cfgFiles[CONFIG_ANDROID].push_back("android_medium.cfg"); - m_cfgFiles[CONFIG_ANDROID].push_back("android_high.cfg"); - m_cfgFiles[CONFIG_ANDROID].push_back("android_veryhigh.cfg"); - m_cfgFiles[CONFIG_IOS].push_back("ios_low.cfg"); - m_cfgFiles[CONFIG_IOS].push_back("ios_medium.cfg"); - m_cfgFiles[CONFIG_IOS].push_back("ios_high.cfg"); - m_cfgFiles[CONFIG_IOS].push_back("ios_veryhigh.cfg"); -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_low.cfg");\ - m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_medium.cfg");\ - m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_high.cfg"); - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - // Since the layout order is set by the .ui file we need to match the order here so that tabbing works correctly. - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_gameeffects.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_light.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_objectdetail.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_particles.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_physics.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_postprocessing.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_quality.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_shading.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_shadows.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_sound.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_texture.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_textureresolution.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_volumetriceffects.cfg"); - m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_water.cfg"); - m_cvarGroupOrder.push_back("miscellaneous"); - - m_platformStrings.push_back(AZStd::make_pair("PC", CONFIG_PC)); - m_platformStrings.push_back(AZStd::make_pair("OSX Metal", CONFIG_OSX_METAL)); - m_platformStrings.push_back(AZStd::make_pair("Android", CONFIG_ANDROID)); - m_platformStrings.push_back(AZStd::make_pair("iOS", CONFIG_IOS)); -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - m_platformStrings.push_back(AZStd::make_pair(PublicAuxName2, CONFIG_##CODENAME)); - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - m_platformStrings.push_back(AZStd::make_pair("Custom", CONFIG_INVALID_PLATFORM)); - - for (auto& platformString : m_platformStrings) - { - QString platform = platformString.first.c_str(); - m_ui->m_platformEntry->addItem(platform); - } - - QSettings settings("O3DE", "O3DE"); - settings.beginGroup("GraphicsSettingsDialog"); - - if (settings.contains("Platform")) - { - QString platformName = settings.value("Platform").toString(); - AZStd::string azPlatform = platformName.toUtf8().data(); - m_currentPlatform = GetConfigPlatformFromName(azPlatform); - if (m_currentPlatform == CONFIG_INVALID_PLATFORM) - { - ShowCustomSpecOption(true); - } - } - - settings.endGroup(); - - SetPlatformEntry(m_currentPlatform); - - BuildUI(); - - connect(m_ui->m_graphicsSettingsTreeView, &QTreeView::collapsed, this, [&](const QModelIndex& index) { SetCollapsed(index, true); }); - connect(m_ui->m_graphicsSettingsTreeView, &QTreeView::expanded, this, [&](const QModelIndex& index) { SetCollapsed(index, false); }); - - AzQtComponents::StyleManager::setStyleSheet(this, "style:GraphicsSettingsDialog.qss"); -} - -GraphicsSettingsDialog::~GraphicsSettingsDialog() -{ - QSettings settings("O3DE", "O3DE"); - settings.beginGroup("GraphicsSettingsDialog"); - - auto platformCheck = [this](AZStd::pair& stringConfigPair) { return stringConfigPair.second == m_currentPlatform; }; - auto platformStringsIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformCheck); - if (platformStringsIterator != m_platformStrings.end()) - { - settings.setValue("Platform", platformStringsIterator->first.c_str()); - } - else - { - settings.remove("Platform"); - } - - settings.beginGroup("cvarGroup"); - - for (auto& collapseIterator : m_uiCollapseGroup) - { - settings.setValue(collapseIterator->m_groupName, collapseIterator->m_isCollapsed); - } - - settings.endGroup(); - settings.endGroup(); - settings.sync(); - - for (CollapseGroup* group : m_uiCollapseGroup) - { - // Destructor of CollapseGroup will set the members - // pointing to nullptr. The actually destruction of the - // widgets will be done on destruction of m_ui - delete group; - } - - for (ParameterWidget* widget : m_parameterWidgets) - { - // Destructor of ParameterWidget will set the members - // pointing to nullptr. The actually destruction of the - // widgets will be done on destruction of m_ui - delete widget; - } - - // Delete m_ui will destruct all the UI elements with in the ui file - // Since m_ui is a QScopedPointer which will cleanup itself on the end - // of the scope. -} - -void GraphicsSettingsDialog::SetSettingsTree(int numColumns) -{ - m_graphicsSettingsModel->clear(); - m_uiCollapseGroup.clear(); - m_graphicsSettingsModel->setColumnCount(numColumns); - - for (int i = 1; i < numColumns; ++i) - { - m_ui->m_graphicsSettingsTreeView->header()->setSectionResizeMode(i, QHeaderView::Stretch); - } - - m_ui->m_graphicsSettingsTreeView->setColumnWidth(0, 200); - m_ui->m_graphicsSettingsTreeView->header()->setMinimumSectionSize(100); - - m_graphicsSettingsModel->setHeaderData(0, Qt::Horizontal, "Properties"); - - auto parentItem = m_graphicsSettingsModel->invisibleRootItem(); - - for (int i = 0; i < aznumeric_cast(GraphicsSettings::numSettings); ++i) - { - QStandardItem* row = new QStandardItem(); - row->setData(groupNames[i], Qt::DisplayRole); - parentItem->appendRow(row); - SetCollapsedLayout(groupNames[i].replace(" ", ""), row); - } - m_numColumns = numColumns; - - m_cvarGroupData["Config/CVarGroups/sys_spec_gameeffects.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::GameEffects)); - m_cvarGroupData["Config/CVarGroups/sys_spec_light.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Light)); - m_cvarGroupData["Config/CVarGroups/sys_spec_objectdetail.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::ObjectDetail)); - m_cvarGroupData["Config/CVarGroups/sys_spec_particles.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Particles)); - m_cvarGroupData["Config/CVarGroups/sys_spec_physics.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Physics)); - m_cvarGroupData["Config/CVarGroups/sys_spec_postprocessing.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::PostProcessing)); - m_cvarGroupData["Config/CVarGroups/sys_spec_quality.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Quality)); - m_cvarGroupData["Config/CVarGroups/sys_spec_shading.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Shading)); - m_cvarGroupData["Config/CVarGroups/sys_spec_shadows.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Shadows)); - m_cvarGroupData["Config/CVarGroups/sys_spec_sound.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Sound)); - m_cvarGroupData["Config/CVarGroups/sys_spec_texture.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Texture)); - m_cvarGroupData["Config/CVarGroups/sys_spec_textureresolution.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::TextureResolution)); - m_cvarGroupData["Config/CVarGroups/sys_spec_volumetriceffects.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::VolumetricEffects)); - m_cvarGroupData["Config/CVarGroups/sys_spec_water.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Water)); - m_cvarGroupData["miscellaneous"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Miscellaneous)); -} - -void GraphicsSettingsDialog::OnLoadConfigurationEntry(const char* strKey, const char* strValue, const char* strGroup) -{ - AZStd::string key = strKey; - ICVar* cvar = gEnv->pConsole->GetCVar(strKey); - - if (cvar) - { - AZStd::transform(key.begin(), key.end(), key.begin(), tolower); - if (azstricmp(key.c_str(), "sys_spec_full") == 0 || key.find("sys_spec_") == key.npos) - { - int type = cvar->GetType(); - AZStd::any val; - if (type == CVAR_INT) - { - val = atoi(strValue); - } - else if (type == CVAR_FLOAT) - { - val = static_cast(atof(strValue)); - } - else - { - val = AZStd::string(strValue); - } - - // Platform cfg file (ex. pc_veryhigh.cfg) - if (strGroup[0] == '\0') - { - // New cvar loaded into map - if (m_cVarTracker.find(key) == m_cVarTracker.end()) - { - m_cVarTracker[key].type = type; - m_cVarTracker[key].cvarGroup = "miscellaneous"; - AZStd::any empty; - if (type == CVAR_INT) - { - empty = 0; - } - else if (type == CVAR_FLOAT) - { - empty = 0.0f; - } - else - { - empty = AZStd::string(""); - } - m_cVarTracker[key].fileVals.resize(m_numSpecLevels, CVarFileStatus(empty, empty, empty)); - } - - m_cVarTracker[key].fileVals[m_currentSpecIndex].editedValue = val; - m_cVarTracker[key].fileVals[m_currentSpecIndex].overwrittenValue = val; - } - // default group in sys_spec cfg file - else if (azstricmp(strGroup, "default") == 0) - { - CVarFileStatus defaultVal(val, val, val); - if (m_cVarTracker.find(key) == m_cVarTracker.end()) - { - // New cvar loaded into map - CVarInfo& currentCVar = m_cVarTracker[key]; - currentCVar.type = cvar->GetType(); - currentCVar.fileVals.resize(m_numSpecLevels, defaultVal); - } - else - { - // Reset values, if there's a platform override it always follows the sys_spec_*.cfg files. - // Resetting avoids the issue where some spec levels are never set because of an extra platform - // override load happening earlier just to store the value of sys_spec_full. - for (int specLevel = 0; specLevel < m_numSpecLevels; ++specLevel) - { - m_cVarTracker[key].fileVals[specLevel] = defaultVal; - } - } - // Overwrite miscellaneous if mentioned in platform config file - m_cVarTracker[key].cvarGroup = m_currentConfigFilename; - } - // specific index in sys_spec cfg file - else - { - int group = 0; - - if (azsscanf(strGroup, "%d", &group) == 1) - { - auto sysSpecFull = m_cVarTracker.find("sys_spec_full"); - if (sysSpecFull != m_cVarTracker.end()) - { - CVarFileStatus indexAssignment(val, val, val); - for (int specLevel = 0; specLevel < m_numSpecLevels; ++specLevel) - { - // Only apply cvar change to configurations with sys_spec_Full matching the index - int overwrittenValue = 0; - if (AZStd::any_numeric_cast(&sysSpecFull->second.fileVals[specLevel].overwrittenValue, overwrittenValue) && group == overwrittenValue) - { - m_cVarTracker[key].fileVals[specLevel] = indexAssignment; - } - } - } - } - } - } - } -} - -// Loads UI column for specific cfg file (ex. pc_low.cfg) -void GraphicsSettingsDialog::BuildColumn(int specLevel) -{ - if (specLevel < 0 || specLevel >= m_numSpecLevels) - { - return; - } - - for (auto& it : m_cvarGroupData) - { - it.second.m_currentRow = 0; - } - - for (auto& it : m_cVarTracker) - { - QString str = it.first.c_str(); - QWidget* input = nullptr; - if (it.second.type == CVAR_INT) - { - AzQtComponents::SpinBox* intval = new AzQtComponents::SpinBox(nullptr); - intval->setFocusPolicy(Qt::StrongFocus); - intval->setMaximum(INT32_MAX); - intval->setMinimum(INT32_MIN); - int editedValue; - if (AZStd::any_numeric_cast(&it.second.fileVals[specLevel].editedValue, editedValue)) - { - intval->setValue(editedValue); - } - m_cvarGroupData[it.second.cvarGroup].m_cvarSpinBoxes.push_back(intval); - connect(intval, SIGNAL(valueChanged(int)), this, SLOT(CVarChanged(int))); - input = intval; - } - else if (it.second.type == CVAR_FLOAT) - { - AzQtComponents::DoubleSpinBox* doubleval = new AzQtComponents::DoubleSpinBox(nullptr); - doubleval->setFocusPolicy(Qt::StrongFocus); - doubleval->setMaximum(FLT_MAX); - doubleval->setMinimum(-FLT_MAX); - float editedValue; - if (AZStd::any_numeric_cast(&it.second.fileVals[specLevel].editedValue, editedValue)) - { - doubleval->setValue(editedValue); - } - m_cvarGroupData[it.second.cvarGroup].m_cvarDoubleSpinBoxes.push_back(doubleval); - connect(doubleval, SIGNAL(valueChanged(double)), this, SLOT(CVarChanged(double))); - input = doubleval; - } - else - { - QLineEdit* stringval = new QLineEdit(nullptr); - AZStd::string* editedValue = AZStd::any_cast(&it.second.fileVals[specLevel].editedValue); - stringval->setText(editedValue->c_str()); - m_cvarGroupData[it.second.cvarGroup].m_cvarLineEdits.push_back(stringval); - connect(stringval, SIGNAL(textChanged(const QString&)), this, SLOT(CVarChanged(const QString&))); - input = stringval; - } - - if (input) - { - input->setObjectName(str); - input->setProperty("specLevel", specLevel); - QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - sizePolicy.setHeightForWidth(input->sizePolicy().hasHeightForWidth()); - input->setSizePolicy(sizePolicy); - input->setMinimumSize(QSize(INPUT_MIN_WIDTH, INPUT_MIN_HEIGHT)); - QStandardItem* parentItem = m_cvarGroupData[it.second.cvarGroup].m_treeRowItem; - QModelIndex parentIndex = parentItem->index(); - QModelIndex thisIndex = m_graphicsSettingsModel->index(m_cvarGroupData[it.second.cvarGroup].m_currentRow++, specLevel + CVAR_VALUE_COLUMN_OFFSET, parentIndex); - m_ui->m_graphicsSettingsTreeView->setIndexWidget(thisIndex, input); - m_parameterWidgets.push_back(new ParameterWidget(input, it.first.c_str())); - m_cvarGroupData[it.second.cvarGroup].m_widgetInsertOrder.push_back(input); - } - } -} - -void GraphicsSettingsDialog::LoadPlatformConfigurations() -{ - const int numColumns = m_cfgFiles[m_currentPlatform].size() + 1; - SetSettingsTree(numColumns); - - for (ParameterWidget* widget : m_parameterWidgets) - { - delete widget; - } - m_parameterWidgets.clear(); - - m_ui->m_applyButton->setEnabled(false); - m_dirtyCVarCount = 0; - - // Load platform cfg files to load in sys_spec_Full - for (size_t cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex) - { - m_currentSpecIndex = cfgFileIndex; - m_currentConfigFilename = m_cfgFiles[m_currentPlatform][cfgFileIndex]; - GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true); - } - - if (m_cVarTracker.find("sys_spec_full") == m_cVarTracker.end()) - { - m_cVarTracker.clear(); - CleanUI(); - ShowCategories(false); - QMessageBox::warning(this, "Warning", "Invalid custom spec file (missing sys_spec_full).", - QMessageBox::Ok); - return; - } - - // Load sys_spec cfgs based on sys_spec_Full values - LoadCVarGroupDirectory(m_cvarGroupsFolder); - - setUpdatesEnabled(false); - - // Reload platform cfg files to override sys_spec index assignments and load rows with filenames of given platform - for (size_t cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex) - { - m_currentSpecIndex = cfgFileIndex; - m_currentConfigFilename = m_cfgFiles[m_currentPlatform][cfgFileIndex]; - GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true); - - /*CVarGroupInfo& specFileGroup =*/ m_cvarGroupData["SpecFile"]; - m_graphicsSettingsModel->setHeaderData(cfgFileIndex + CVAR_VALUE_COLUMN_OFFSET, Qt::Horizontal, QApplication::translate("GraphicsSettingsDialog", m_cfgFiles[m_currentPlatform][cfgFileIndex].c_str())); - } - - // Loads column of cvar names - for (auto& it : m_cVarTracker) - { - QLabel* cVarLabel = new QLabel(nullptr); - QString str = it.first.c_str(); - QString strLabel = str + "Label"; - cVarLabel->setObjectName(strLabel); - QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - sizePolicy.setHeightForWidth(cVarLabel->sizePolicy().hasHeightForWidth()); - cVarLabel->setSizePolicy(sizePolicy); - cVarLabel->setMinimumSize(QSize(INPUT_MIN_WIDTH, INPUT_MIN_HEIGHT)); - cVarLabel->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter); - QStandardItem* cVarItem = new QStandardItem(); - cVarItem->setData(QApplication::translate("GraphicsSettingsDialog", it.first.c_str(), 0), Qt::DisplayRole); - QList items{ cVarItem }; - for (int i = 1; i < numColumns; ++i) - { - items << new QStandardItem(); - } - m_cvarGroupData[it.second.cvarGroup].m_treeRowItem->appendRow(items); - cVarLabel->setText(QApplication::translate("GraphicsSettingsDialog", it.first.c_str(), 0)); - m_cvarGroupData[it.second.cvarGroup].m_cvarLabels.push_back(cVarLabel); - - if (ICVar* cvar = gEnv->pConsole->GetCVar(it.first.c_str())) - { - cVarLabel->setToolTip(cvar->GetHelp()); - } - } - - // Loads columns of cvar values for each platform cfg file - for (int cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex) - { - BuildColumn(cfgFileIndex); - } - - // Remove any section that has no visible controls - for (auto& it : m_cvarGroupData) - { - int totalControlCount = 0; - CVarGroupInfo& currentCvarGroupInfo = it.second; - totalControlCount += currentCvarGroupInfo.m_cvarDoubleSpinBoxes.size(); - totalControlCount += currentCvarGroupInfo.m_cvarSpinBoxes.size(); - totalControlCount += currentCvarGroupInfo.m_cvarLineEdits.size(); - totalControlCount += currentCvarGroupInfo.m_platformLabels.size(); - - if (totalControlCount == 0) - { - if (currentCvarGroupInfo.m_treeRowItem) - { - int i = 0; - for (auto& collapseIterator : m_uiCollapseGroup) - { - if (collapseIterator->m_groupRow == currentCvarGroupInfo.m_treeRowItem) - { - m_uiCollapseGroup.remove(i); - break; - } - ++i; - } - m_graphicsSettingsModel->removeRow(currentCvarGroupInfo.m_treeRowItem->row()); - } - } - } - - setUpdatesEnabled(true); - - QSettings settings("O3DE", "O3DE"); - settings.beginGroup("GraphicsSettingsDialog"); - settings.beginGroup("cvarGroup"); - - for (auto& collapseIterator : m_uiCollapseGroup) - { - bool groupCollapsed = settings.value(collapseIterator->m_groupName, collapseIterator->m_isCollapsed).toBool(); - if (collapseIterator->m_isCollapsed != groupCollapsed) - { - collapseIterator->ToggleCollapsed(); - } - } - - settings.endGroup(); - settings.endGroup(); -} - -void GraphicsSettingsDialog::LoadCVarGroupDirectory(const AZStd::string& path) -{ - AZ::IO::LocalFileIO::FindFilesCallbackType fileFinderCb; - fileFinderCb = [&](const char* fullPath) -> bool - { - if (gEnv->pFileIO->IsDirectory(fullPath)) - { - // recurse into subdirectory - gEnv->pFileIO->FindFiles(fullPath, "*.cfg", fileFinderCb); - } - else - { - m_currentConfigFilename = fullPath; - GetISystem()->LoadConfiguration(fullPath, this, false); - } - - return true; // keep searching - }; - - gEnv->pFileIO->FindFiles(path.c_str(), "*.cfg", fileFinderCb); -} - -//Build UI, link signals and set the data for device list. -void GraphicsSettingsDialog::BuildUI() -{ - connect(m_ui->m_cancelButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::reject); - connect(m_ui->m_applyButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::accept); - connect(m_ui->m_platformEntry, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(PlatformChanged(const QString&))); - connect(m_ui->m_selectCustomSpecButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::OpenCustomSpecDialog); - - if (!m_cfgFiles[m_currentPlatform].empty()) - { - LoadPlatformConfigurations(); - } - else - { - m_cVarTracker.clear(); - CleanUI(); - ShowCategories(false); - } -} - -void GraphicsSettingsDialog::CleanUI() -{ - setUpdatesEnabled(false); - - QSettings settings("O3DE", "O3DE"); - settings.beginGroup("GraphicsSettingsDialog"); - settings.beginGroup("cvarGroup"); - - for (auto& collapseIterator : m_uiCollapseGroup) - { - settings.setValue(collapseIterator->m_groupName, collapseIterator->m_isCollapsed); - } - - settings.endGroup(); - settings.endGroup(); - settings.sync(); - - m_cVarTracker.clear(); - - // Uncollapse groups - for (auto& collapseIt : m_uiCollapseGroup) - { - if (collapseIt->m_isCollapsed) - { - collapseIt->ToggleCollapsed(); - } - } - - setUpdatesEnabled(true); -} - -void GraphicsSettingsDialog::ShowCategories(bool show) -{ - if (m_showCategories == show) - { - return; - } - - m_showCategories = show; - m_ui->m_graphicsSettingsTreeView->setVisible(show); -} - -void GraphicsSettingsDialog::ShowCustomSpecOption(bool show) -{ - if (m_showCustomSpec == show) - { - return; - } - - m_showCustomSpec = show; - m_ui->m_selectCustomSpecButton->setVisible(m_showCustomSpec); - m_ui->m_lineSpacer->setVisible(m_showCustomSpec); -} - -void GraphicsSettingsDialog::PlatformChanged(const QString& platform) -{ - bool change = true; - if (m_dirtyCVarCount > 0 && !SendUnsavedChangesWarning(false)) - { - change = false; - } - - if (change) - { - AZStd::string azPlatform = platform.toStdString().c_str(); - - m_currentPlatform = GetConfigPlatformFromName(azPlatform); - if (m_currentPlatform == CONFIG_INVALID_PLATFORM) // "Custom" selected - { - ShowCustomSpecOption(true); - CleanUI(); - if (m_cfgFiles[CONFIG_INVALID_PLATFORM].empty()) // if we don't have a custom spec - { - ShowCategories(false); - m_ui->m_applyButton->setEnabled(false); - m_dirtyCVarCount = 0; - } - else - { - ShowCategories(true); - LoadPlatformConfigurations(); - } - } - else - { - ShowCustomSpecOption(false); - ShowCategories(true); - CleanUI(); - LoadPlatformConfigurations(); - } - } - else - { - m_ui->m_platformEntry->blockSignals(true); - SetPlatformEntry(m_currentPlatform); - m_ui->m_platformEntry->blockSignals(false); - } -} - -bool GraphicsSettingsDialog::SendUnsavedChangesWarning(bool cancel) -{ - int result = QMessageBox::Yes; - - if (cancel) - { - result = QMessageBox::question(this, "Warning", "There are currently unsaved changed. Are you sure you want to cancel?", - QMessageBox::Yes, QMessageBox::No); - } - else - { - result = QMessageBox::question(this, "Warning", "There are currently unsaved changed. Are you sure you want to change configurations?", - QMessageBox::Yes, QMessageBox::No); - } - - return (result == QMessageBox::Yes); -} - -bool GraphicsSettingsDialog::CVarChanged(AZStd::any val, const char* cvarName, int specLevel) -{ - // Checking if the edited value (before change) is equal to the overwritten value - bool dirtyBefore = false; - AZStd::string azcvarName = cvarName; - AZStd::pair cvarInfo = AZStd::make_pair(azcvarName, m_cVarTracker[cvarName]); - if (CheckCVarStatesForDiff(&cvarInfo, specLevel, EDITED_OVERWRITTEN_COMPARE)) - { - dirtyBefore = true; - } - - if (azstricmp(cvarName, "sys_spec_full") == 0) - { - //Pop out the warning dialog for sys_spec_Full since all cvars will be changed - int result = QMessageBox::Ok; - - result = QMessageBox::question(this, "Warning", "Modifying sys_spec_full will override any unsaved changes.", - QMessageBox::Ok, QMessageBox::Cancel); - - // Cancel - Change sys_spec_full qspinbox value back - if (result == QMessageBox::Cancel) - { - return false; - } - else // OK - reload column - { - // Updating sys_spec_full for when adding cvargroup directory - m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val; - gEnv->pSystem->AddCVarGroupDirectory(m_cvarGroupsFolder); - m_currentConfigFilename = m_cfgFiles[m_currentPlatform][specLevel]; - m_currentSpecIndex = specLevel; - GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true); - // Updating sys_spec_full since overwritten from loading platform cfg - m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val; - BuildColumn(specLevel); - } - } - else - { - m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val; - } - - // Checking if the newly edited value is equal to the overwritten value - cvarInfo = AZStd::make_pair(azcvarName, m_cVarTracker[cvarName]); - if (CheckCVarStatesForDiff(&cvarInfo, specLevel, EDITED_OVERWRITTEN_COMPARE)) - { - if (!dirtyBefore) - { - m_ui->m_applyButton->setEnabled(true); - m_dirtyCVarCount++; - } - } - else - { - if (dirtyBefore) - { - m_dirtyCVarCount--; - if (m_dirtyCVarCount == 0) - { - m_ui->m_applyButton->setEnabled(false); - } - } - } - - return true; -} - -void GraphicsSettingsDialog::CVarChanged(int i) -{ - AzQtComponents::SpinBox* box = static_cast(sender()); - QString str = box->objectName(); - QByteArray ba = str.toUtf8(); - const char* cvarName = ba.data(); - - int specLevel = box->property("specLevel").toInt(); - - AZStd::any val; - val = i; - - if (!CVarChanged(val, cvarName, specLevel)) - { - // sys_spec_full warning cancelled - box->blockSignals(true); - int editedValue; - if (AZStd::any_numeric_cast(&m_cVarTracker[cvarName].fileVals[specLevel].editedValue, editedValue)) - { - box->setValue(editedValue); - } - box->blockSignals(false); - } -} - -void GraphicsSettingsDialog::CVarChanged(double d) -{ - AzQtComponents::DoubleSpinBox* box = static_cast(sender()); - QString str = box->objectName(); - QByteArray ba = str.toUtf8(); - const char* cvarName = ba.data(); - - AZStd::any val; - val = d; - - int specLevel = box->property("specLevel").toInt(); - - if (!CVarChanged(val, cvarName, specLevel)) - { - // only can return false from sys_spec_full, which is an int cvar - } -} - -void GraphicsSettingsDialog::CVarChanged(const QString& s) -{ - QLineEdit* box = qobject_cast(sender()); - QString str = box->objectName(); - QByteArray ba = str.toUtf8(); - const char* cvarName = ba.data(); - - AZStd::any val; - val = AZStd::string(s.toStdString().c_str()); - - int specLevel = box->property("specLevel").toInt(); - - if (!CVarChanged(val, cvarName, specLevel)) - { - // only can return false from sys_spec_full, which is an int cvar - } -} - -// Returns true if there is a difference between the two cvar states -bool GraphicsSettingsDialog::CheckCVarStatesForDiff(AZStd::pair* it, int cfgFileIndex, CVarStateComparison cmp) -{ - if (it->second.type == CVAR_INT) - { - int editedVal, overwrittenVal, originalVal; - if (AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].editedValue, editedVal) && - AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue, overwrittenVal) && - AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].originalValue, originalVal)) - { - if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal != overwrittenVal) || - (cmp == EDITED_ORIGINAL_COMPARE && editedVal != originalVal) || - (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal != originalVal)) - { - return true; - } - } - } - else if (it->second.type == CVAR_FLOAT) - { - float editedVal, overwrittenVal, originalVal; - if (AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].editedValue, editedVal) && - AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue, overwrittenVal) && - AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].originalValue, originalVal)) - { - if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal != overwrittenVal) || - (cmp == EDITED_ORIGINAL_COMPARE && editedVal != originalVal) || - (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal != originalVal)) - { - return true; - } - } - } - else - { - AZStd::string editedVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].editedValue); - AZStd::string overwrittenVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue); - AZStd::string originalVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].originalValue); - if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal.compare(overwrittenVal) != 0) || - (cmp == EDITED_ORIGINAL_COMPARE && editedVal.compare(originalVal) != 0) || - (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal.compare(originalVal) != 0)) - { - return true; - } - } - return false; -} - -/////////////////////////////////////////////////////////////////////// -// settings file management -void GraphicsSettingsDialog::reject() -{ - if (m_dirtyCVarCount > 0) - { - if (SendUnsavedChangesWarning(true)) - { - QDialog::reject(); - } - } - else - { - QDialog::reject(); - } -} - -void GraphicsSettingsDialog::accept() -{ - int result = QMessageBox::Yes; - - //Pop out the warning dialog for customized setting - result = QMessageBox::question(this, "Warning", "A non-tested setting could potentially crash the game if the setting does not match the device. Are you sure you want to apply the customized setting?", - QMessageBox::Yes, QMessageBox::No); - - //Save and exit - if (result == QMessageBox::Yes) - { - SaveSystemSettings(); - } -} - -void GraphicsSettingsDialog::OpenCustomSpecDialog() -{ - AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath(); - projectPath /= SETTINGS_FILE_PATH.toUtf8().constData(); - QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast(projectPath.Native().size())); - - CAutoDirectoryRestoreFileDialog importCustomSpecDialog(QFileDialog::AcceptOpen, QFileDialog::ExistingFile, ".cfg", settingsPath, CFG_FILEFILTER, {}, {}, this); - - if (importCustomSpecDialog.exec()) - { - QString file = importCustomSpecDialog.selectedFiles().first(); - if (!file.isEmpty()) - { - ApplyCustomSpec(file); - } - } -} - -void GraphicsSettingsDialog::ApplyCustomSpec(const QString& customFilePath) -{ - if (customFilePath.isEmpty()) - { - return; - } - - QFile customFile(customFilePath); - if (!customFile.exists()) - { - QMessageBox::warning(this, "Warning", "Could not find custom spec file.", - QMessageBox::Ok); - return; - } - - bool change = true; - if (m_dirtyCVarCount > 0 && !SendUnsavedChangesWarning(false)) - { - change = false; - } - - if (change) - { - AZStd::string filename = customFilePath.toStdString().c_str(); - filename = filename.substr(filename.find_last_of('/') + 1); - - m_currentPlatform = CONFIG_INVALID_PLATFORM; - - bool alreadyLoaded = IsCustomSpecAlreadyLoaded(filename); - if (m_cfgFiles[CONFIG_INVALID_PLATFORM].size() < m_numSpecLevels && !alreadyLoaded) - { - m_cfgFiles[CONFIG_INVALID_PLATFORM].push_back(filename); - } - else if (alreadyLoaded) - { - QMessageBox::warning(this, "Warning", "The selected custom spec file is already loaded. No changes have been made.", - QMessageBox::Ok); - return; - } - - if (m_cfgFiles[CONFIG_INVALID_PLATFORM].size() == m_numSpecLevels) - { - m_ui->m_selectCustomSpecButton->setEnabled(false); - } - - ShowCategories(true); - - CleanUI(); - - LoadPlatformConfigurations(); - } -} - -void GraphicsSettingsDialog::UnloadCustomSpec(int specLevel) -{ - if (specLevel < 0 || specLevel >= m_cfgFiles[CONFIG_INVALID_PLATFORM].size()) - { - return; - } - - bool shouldUnload = m_dirtyCVarCount <= 0 || SendUnsavedChangesWarning(false); - - if (shouldUnload) - { - m_cfgFiles[CONFIG_INVALID_PLATFORM].erase(m_cfgFiles[CONFIG_INVALID_PLATFORM].begin() + specLevel); - - CleanUI(); - - if (!m_cfgFiles[CONFIG_INVALID_PLATFORM].empty()) - { - LoadPlatformConfigurations(); - } - else - { - ShowCategories(false); - } - } -} - -bool GraphicsSettingsDialog::IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const -{ - auto& customConfigFilenames = m_cfgFiles.at(CONFIG_INVALID_PLATFORM); - const auto& findResult = AZStd::find(customConfigFilenames.begin(), customConfigFilenames.end(), filename.c_str()); - - return findResult != customConfigFilenames.end(); -} - -void GraphicsSettingsDialog::SetCollapsedLayout(const QString& groupName, QStandardItem* groupRow) -{ - CollapseGroup* cgroup = new CollapseGroup(m_ui->m_graphicsSettingsTreeView); - cgroup->m_groupName = groupName; - cgroup->m_groupRow = groupRow; - m_uiCollapseGroup.push_back(cgroup); -} - -void GraphicsSettingsDialog::SetPlatformEntry(ESystemConfigPlatform platform) -{ - auto platformCheck = [&platform](AZStd::pair& stringConfigPair) { return stringConfigPair.second == platform; }; - auto platformStringsIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformCheck); - if (platformStringsIterator != m_platformStrings.end()) - { - int platformIndex = m_ui->m_platformEntry->findText(platformStringsIterator->first.c_str()); - m_ui->m_platformEntry->setCurrentIndex(platformIndex); - } - else - { - AZ_Assert(false, "Platform not found in platform strings vector."); - } -} - -ESystemConfigPlatform GraphicsSettingsDialog::GetConfigPlatformFromName(const AZStd::string& platformName) -{ - ESystemConfigPlatform configPlatform = CONFIG_INVALID_PLATFORM; - - auto platformNameCheck = [&platformName](AZStd::pair& stringConfigPair) { return (stringConfigPair.first == platformName); }; - auto configPlatformIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformNameCheck); - if (configPlatformIterator != m_platformStrings.end()) - { - configPlatform = configPlatformIterator->second; - } - else - { - AZ_Assert(false, "Platform name not found in platform strings vector."); - } - - return configPlatform; -} - -// Save the current UI options to system qsettings -void GraphicsSettingsDialog::SaveSystemSettings() -{ - AZStd::vector successFiles; - AZStd::vector nochangeFiles; - - for (int cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex) - { - const QString eq = " = "; - const QString cvarGroupString1 = "\n------------------------\n-- "; - const QString cvarGroupString2 = "\n------------------------\n"; - QString commandList = ""; - - int sysSpecFull; - if (AZStd::any_numeric_cast(&m_cVarTracker["sys_spec_full"].fileVals[cfgFileIndex].editedValue, sysSpecFull)) - { - commandList += "sys_spec_full" + eq + QString::number(sysSpecFull) + '\n'; - } - - QMap cvarGroupStrings; - - // Set to true as soon as cvar is found which is unique from current cfg file and index assignment - bool saveOut = false; - - // Adding any dirty cvars not equal to sys_spec_full or any cvar in miscellaneous to command list - for (auto& it : m_cVarTracker) - { - if ((CheckCVarStatesForDiff(&it, cfgFileIndex, EDITED_ORIGINAL_COMPARE) || it.second.cvarGroup == "miscellaneous") && azstricmp(it.first.c_str(), "sys_spec_full")) - { - AZStd::string cvarGroup = it.second.cvarGroup; - if (azstricmp(cvarGroup.c_str(), "miscellaneous") != 0) - { - int fileIndex = cvarGroup.find_last_of('/') + 1; - cvarGroup = cvarGroup.substr(fileIndex, cvarGroup.size() - fileIndex - 4); - } - QString qcvarGroup = cvarGroup.c_str(); - if (cvarGroupStrings.find(qcvarGroup) == cvarGroupStrings.end()) - { - cvarGroupStrings[qcvarGroup] = cvarGroupString1 + qcvarGroup + cvarGroupString2; - } - - if (it.second.type == CVAR_INT) - { - int val; - if (AZStd::any_numeric_cast(&it.second.fileVals[cfgFileIndex].editedValue, val)) - { - cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + QString::number(val) + '\n'; - } - } - else if (it.second.type == CVAR_FLOAT) - { - float val; - if (AZStd::any_numeric_cast(&it.second.fileVals[cfgFileIndex].editedValue, val)) - { - cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + QString::number(val) + '\n'; - } - } - else - { - cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + AZStd::any_cast(it.second.fileVals[cfgFileIndex].editedValue).c_str() + '\n'; - } - } - - if (!saveOut) - { - saveOut = CheckCVarStatesForDiff(&it, cfgFileIndex, EDITED_OVERWRITTEN_COMPARE); - } - } - - // Adding the project name to the path so that the file is created there if it doesn't already exist - // as we don't want to modify the version in Engine/config. - AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath(); - projectPath /= SETTINGS_FILE_PATH.toUtf8().constData(); - QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast(projectPath.Native().size())); - - QString settingsFile = settingsPath + m_cfgFiles[m_currentPlatform][cfgFileIndex].c_str(); - - // Check if current settings differ from existing cfg - if (saveOut) - { - // Adding any dirty cvars not equal to sys_spec_full to command list - for (auto& it : cvarGroupStrings) - { - commandList += it; - } - - if (CFileUtil::OverwriteFile(settingsFile.toStdString().c_str())) - { - if (!CFileUtil::CreateDirectory(settingsPath.toStdString().c_str())) - { - QMessageBox::warning(this, "Warning", "Could not create the directory for file \"" + settingsFile + "\". Failed to apply Graphics Setting.", - QMessageBox::Ok); - continue; - } - - QByteArray dataArray = commandList.toUtf8().data(); - - QFile file(settingsFile); - if (!file.open(QIODevice::WriteOnly) || file.write(dataArray) != dataArray.size()) - { - QMessageBox::warning(this, "Warning", "Could not write settings to file \"" + settingsFile + ". Failed to apply Graphics Setting.", - QMessageBox::Ok); - file.close(); - continue; - } - - successFiles.push_back(settingsFile); - - // Update platform cvars to reflect new values - for (auto& it : m_cVarTracker) - { - it.second.fileVals[cfgFileIndex].overwrittenValue = it.second.fileVals[cfgFileIndex].editedValue; - } - - file.close(); - } - else - { - QMessageBox::warning(this, "Warning", "Could not check out or make file writable: \"" + settingsFile + "\". Failed to apply Graphics Setting.", - QMessageBox::Ok); - } - } - else - { - nochangeFiles.push_back(settingsFile); - } - } - - // Print list of files which had no changes made - if (nochangeFiles.size() > 0) - { - QString message = "No changes have been made to the following files:\n"; - for (int i = 0; i < nochangeFiles.size(); ++i) - { - message += nochangeFiles[i] + "\n"; - } - QMessageBox::information(this, "Log", message, QMessageBox::Ok); - } - - // Print list of files which were successfully saved - if (successFiles.size() > 0) - { - QString message = "Updated the graphics setting correctly for the following files:\n"; - for (int i = 0; i < successFiles.size(); ++i) - { - message += successFiles[i] + "\n"; - } - QMessageBox::information(this, "Log", message, QMessageBox::Ok); - } - - // if we saved all of the files that we needed to then disable the save button again - if (nochangeFiles.size() + successFiles.size() == m_cfgFiles[m_currentPlatform].size()) - { - m_dirtyCVarCount = 0; - m_ui->m_applyButton->setEnabled(false); - } -} - -void GraphicsSettingsDialog::SetCollapsed(const QModelIndex& index, bool flags) -{ - QStandardItem* item = m_graphicsSettingsModel->itemFromIndex(index); - - for (auto& collapseIterator : m_uiCollapseGroup) - { - if (collapseIterator->m_groupRow == item) - { - collapseIterator->m_isCollapsed = flags; - break; - } - } -} - -///////////////////////////////////////////////////////////////////////// -// Collapse Group -GraphicsSettingsDialog::CollapseGroup::CollapseGroup(QTreeView* treeView) - : m_treeView(treeView) - , m_isCollapsed(true) -{ -} - -void GraphicsSettingsDialog::CollapseGroup::ToggleCollapsed() -{ - m_isCollapsed = !m_isCollapsed; - const QModelIndex index = m_groupRow->index(); - if (m_isCollapsed) - { - m_treeView->collapse(index); - } - else - { - m_treeView->expand(index); - } -} - -/////////////////////////////////////////////////////////////////// -// ParameterWidget -GraphicsSettingsDialog::ParameterWidget::ParameterWidget(QWidget* widget, QString parameterName) - : m_widget(widget) - , m_parameterName(parameterName) -{ - m_widget->setToolTip(GetToolTip()); -} - -QString GraphicsSettingsDialog::ParameterWidget::GetToolTip() const -{ - if (!m_parameterName.isEmpty()) - { - QString tooltipText = QString(PARAMETER_TOOLTIP).arg(m_parameterName); - return tooltipText; - } - return ""; -} - -GraphicsSettingsTreeView::GraphicsSettingsTreeView(QWidget* parent) - : QTreeView(parent) -{ -} - -GraphicsSettingsHeaderView::GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent) - : QHeaderView(orientation, parent) - , m_dialog(dialog) -{ - setDefaultAlignment(Qt::AlignLeft); -} - -bool GraphicsSettingsHeaderView::event(QEvent* e) -{ - if (m_dialog->IsCustom()) - { - GraphicsSettingsTreeView* treeView = qobject_cast(parent()); - if (treeView) - { - switch (e->type()) - { - case QEvent::Enter: - m_index = logicalIndexAt(static_cast(e)->pos()); - if (m_index > 0) - { - treeView->setSortingEnabled(true); - treeView->sortByColumn(m_index, Qt::AscendingOrder); - } - break; - case QEvent::Leave: - treeView->setSortingEnabled(false); - break; - } - } - } - return QHeaderView::event(e); -} - -void GraphicsSettingsHeaderView::mouseReleaseEvent(QMouseEvent* e) -{ - AZ_UNUSED(e); - if (QMessageBox::question( - this, QObject::tr("Unload Resource"), - QObject::tr("Are you sure you want to unload the resource?"), - QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) - { - m_dialog->UnloadCustomSpec(m_index - 1); - } - -} - -void GraphicsSettingsHeaderView::mouseMoveEvent(QMouseEvent* e) -{ - AZ_UNUSED(e); - if (m_dialog->IsCustom()) - { - GraphicsSettingsTreeView* treeView = qobject_cast(parent()); - int index = logicalIndexAt(e->pos()); - if (index != m_index) - { - m_index = index; - if (m_index > 0) - { - treeView->setSortingEnabled(true); - treeView->sortByColumn(m_index, Qt::AscendingOrder); - } - else - { - treeView->setSortingEnabled(false); - } - } - } -} - -GraphicsSettingsModel::GraphicsSettingsModel(QObject* parent) - : QStandardItemModel(parent) -{ -} - -Qt::ItemFlags GraphicsSettingsModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags flags = Qt::NoItemFlags; - - if (index.column() == 0) - { - flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled; - } - return flags; -} - -#include diff --git a/Code/Editor/GraphicsSettingsDialog.h b/Code/Editor/GraphicsSettingsDialog.h deleted file mode 100644 index 66a498cd10..0000000000 --- a/Code/Editor/GraphicsSettingsDialog.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include - -#include -#include -#include - -#include -#endif - -class QGridLayout; -class QLabel; - -namespace Ui -{ - class GraphicsSettingsDialog; -} - -// Description: -// Status of cvar for a specifc platform and spec level -// editedValue - current setting within Graphics Settings Dialog box -// overwrittenValue - original setting from platform config file (set to originalValue if not found) -// originalValue - original settings from sys_spec config file index - -struct CVarFileStatus -{ - AZStd::any editedValue; - AZStd::any overwrittenValue; - AZStd::any originalValue; - CVarFileStatus(AZStd::any edit, AZStd::any over, AZStd::any orig) : editedValue(edit), overwrittenValue(over), originalValue(orig) {} -}; - -// Description: -// Status of specific cvar for Editor mapping -// type - CVAR_INT / CVAR_FLOAT / CVAR_STRING -// cvarGroup - source of cvar (sys_spec_particles, sys_spec_physics, etc.) or "miscellaneous" if only specified in platform config file -// fileVals = CVarFileStatus for each spec level of a specific platform - -struct CVarInfo -{ - int type; - AZStd::string cvarGroup; - AZStd::vector fileVals; -}; - -enum class GraphicsSettings -{ - GameEffects, - Light, - ObjectDetail, - Particles, - Physics, - PostProcessing, - Quality, - Shading, - Shadows, - Sound, - Texture, - TextureResolution, - VolumetricEffects, - Water, - Miscellaneous, - numSettings -}; - -class GraphicsSettingsHeaderView; - -class GraphicsSettingsTreeView - : public QTreeView -{ - Q_OBJECT - -public: - GraphicsSettingsTreeView(QWidget* parent = nullptr); - -}; - -class GraphicsSettingsModel - : public QStandardItemModel -{ - Q_OBJECT - -public: - explicit GraphicsSettingsModel(QObject* parent = 0); - - Qt::ItemFlags flags(const QModelIndex& index) const override; -}; - -class GraphicsSettingsDialog - : public QDialog, - public ILoadConfigurationEntrySink -{ - Q_OBJECT - -public: - - explicit GraphicsSettingsDialog(QWidget* parent = nullptr); - virtual ~GraphicsSettingsDialog(); - - bool IsCustom(void) { return m_showCustomSpec; } - void UnloadCustomSpec(int specLevel); - - // ILoadConfigurationEntrySink - void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) override; - -public slots: - //Accept and reject - void reject() override; - void accept() override; - -private slots: - //Update UIs - void PlatformChanged(const QString& platform); - bool CVarChanged(AZStd::any val, const char* cvarName, int specLevel); - void CVarChanged(int i); - void CVarChanged(double d); - void CVarChanged(const QString& s); - -private: - - // The struct ParameterWidget is used to store the parameter widget - // m_parameterName will be the name of the parameter the widget represent. - struct ParameterWidget - { - ParameterWidget(QWidget* widget, QString parameterName = ""); - - QString GetToolTip() const; - - const char* PARAMETER_TOOLTIP = "The variable will update render parameter \"%1\"."; - QWidget* m_widget; - QString m_parameterName; - }; - - struct CollapseGroup - { - QString m_groupName; - QStandardItem* m_groupRow; - QTreeView* m_treeView; - bool m_isCollapsed; - - CollapseGroup(QTreeView* treeView); - - void ToggleCollapsed(); - }; - - void OpenCustomSpecDialog(); - void ApplyCustomSpec(const QString& customFilePath); - bool IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const; - void SetSettingsTree(int numColumns); - void SetCollapsed(const QModelIndex& index, bool flag); - - enum CVarStateComparison - { - EDITED_OVERWRITTEN_COMPARE = 1, - EDITED_ORIGINAL_COMPARE = 2, - OVERWRITTEN_ORIGINAL_COMPARE = 3, - - END_CVARSTATE_COMPARE, - }; - - bool CheckCVarStatesForDiff(AZStd::pair* it, int cfgFileIndex, CVarStateComparison cmp); - - // Save out settings into project-level cfg files - void SaveSystemSettings(); - - // Load in project-level cfg files for current platform - void LoadPlatformConfigurations(); - // Build UI column for spec level of current platform - void BuildColumn(int specLevel); - // Initial UI building - void BuildUI(); - // Cleaning out UI before loading new platform information - void CleanUI(); - // Shows/hides custom spec option - void ShowCustomSpecOption(bool show); - // Shows/hides category labels and dropdowns - void ShowCategories(bool show); - // Warns about unsaved changes (returns true if accepted) - bool SendUnsavedChangesWarning(bool cancel); - - void LoadCVarGroupDirectory(const AZStd::string& path); - - ///////////////////////////////////////////// - // UI help functions - - // Setup collapsed buttons - void SetCollapsedLayout(const QString& groupName, QStandardItem* groupItem); - // Sets the platform entry index for the given platform - void SetPlatformEntry(ESystemConfigPlatform platform); - // Gets the platform enum given the platform name - ESystemConfigPlatform GetConfigPlatformFromName(const AZStd::string& platformName); - - //////////////////////////////////////////// - // Members - - // Qt values - const int INPUT_MIN_WIDTH = 100; - const int INPUT_MIN_HEIGHT = 20; - const int INPUT_ROW_SPAN = 1; - const int INPUT_COLUMN_SPAN = 1; - const int CVAR_ROW_OFFSET = 2; - const int CVAR_VALUE_COLUMN_OFFSET = 1; - const int PLATFORM_LABEL_ROW = 1; - const int CVAR_LABEL_COLUMN = 1; - - // Tool tips - const QString SETTINGS_FILE_PATH = "Config/spec/"; - const char* CFG_FILEFILTER = "Cfg File(*.cfg);;All files(*)"; - - const int m_numSpecLevels = 4; - - bool m_showCustomSpec; - bool m_showCategories; - GraphicsSettingsModel* m_graphicsSettingsModel; - GraphicsSettingsHeaderView* m_headerView; - int m_numColumns{ 0 }; - - const char* m_cvarGroupsFolder = "Config/CVarGroups"; - - QScopedPointer m_ui; - - QVector m_uiCollapseGroup; - - QVector m_parameterWidgets; - - AZStd::string m_currentConfigFilename; - size_t m_currentSpecIndex; - - // cvar name --> pair(type, CVarStatus for each file) - AZStd::unordered_map m_cVarTracker; - - AZStd::unordered_map > m_cfgFiles; - - AZStd::vector > m_platformStrings; - - struct CVarGroupInfo - { - QVector m_platformLabels; - QVector m_cvarLabels; - QVector m_cvarSpinBoxes; - QVector m_cvarDoubleSpinBoxes; - QVector m_cvarLineEdits; - QVector m_specFileArea; - QVector m_widgetInsertOrder; - QStandardItem* m_treeRowItem; - int m_currentRow; - }; - - AZStd::unordered_map m_cvarGroupData; - AZStd::vector m_cvarGroupOrder; - - ESystemConfigPlatform m_currentPlatform; - - int m_dirtyCVarCount; -}; - -class GraphicsSettingsHeaderView - : public QHeaderView -{ - Q_OBJECT -public: - GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent = nullptr); - -private: - bool event(QEvent* e) override; - void mouseMoveEvent(QMouseEvent* e) override; - void mouseReleaseEvent(QMouseEvent* e) override; - - GraphicsSettingsDialog* m_dialog; - int m_index{ -1 }; -}; - - diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp index 261fab48d1..c7e32fb82a 100644 --- a/Code/Editor/MainWindow.cpp +++ b/Code/Editor/MainWindow.cpp @@ -41,6 +41,7 @@ AZ_POP_DISABLE_WARNING // AzToolsFramework #include +#include #include #include #include @@ -93,6 +94,8 @@ AZ_POP_DISABLE_WARNING #include "AssetEditor/AssetEditorWindow.h" #include "ActionManager.h" +#include + using namespace AZ; using namespace AzQtComponents; using namespace AzToolsFramework; @@ -489,6 +492,16 @@ void MainWindow::Initialize() ActionOverrideRequestBus::Event( GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, this); + if (auto imGuiManager = AZ::Interface::Get()) + { + auto handleImGuiStateChangeFn = [](bool enabled) + { + EditorWindowUIRequestBus::Broadcast(&EditorWindowUIRequests::SetEditorUiEnabled, enabled); + }; + m_handleImGuiStateChangeHandler = ImGui::IImGuiManager::ImGuiSetEnabledEvent::Handler(handleImGuiStateChangeFn); + imGuiManager->ConnectImGuiSetEnabledChangedHandler(m_handleImGuiStateChangeHandler); + } + AzToolsFramework::EditorEventsBus::Broadcast(&AzToolsFramework::EditorEvents::NotifyMainWindowInitialized, this); } @@ -674,49 +687,6 @@ void MainWindow::InitActions() am->AddAction(ID_FILE_PROJECT_MANAGER_SETTINGS, tr("Edit Project Settings...")); am->AddAction(ID_FILE_PROJECT_MANAGER_NEW, tr("New Project...")); am->AddAction(ID_FILE_PROJECT_MANAGER_OPEN, tr("Open Project...")); - am->AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_PC_ENABLEHIGHSPEC, tr("High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_PC_ENABLELOWSPEC, tr("Low")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC, tr("High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC, tr("Low")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC, tr("High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_ANDROID_ENABLELOWSPEC, tr("Low")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_IOS_ENABLEHIGHSPEC, tr("High")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); - am->AddAction(ID_GAME_IOS_ENABLELOWSPEC, tr("Low")).SetCheckable(true) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec); -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#if defined(TOOLS_SUPPORT_JASPER) -#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, jasper) -#endif -#if defined(TOOLS_SUPPORT_PROVO) -#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, provo) -#endif -#if defined(TOOLS_SUPPORT_SALEM) -#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, salem) -#endif -#endif am->AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD, tr("Customize &Keyboard...")) .Connect(&QAction::triggered, this, &MainWindow::ShowKeyboardCustomization); am->AddAction(ID_TOOLS_EXPORT_SHORTCUTS, tr("&Export Keyboard Settings...")) @@ -724,7 +694,6 @@ void MainWindow::InitActions() am->AddAction(ID_TOOLS_IMPORT_SHORTCUTS, tr("&Import Keyboard Settings...")) .Connect(&QAction::triggered, this, &MainWindow::ImportKeyboardShortcuts); am->AddAction(ID_TOOLS_PREFERENCES, tr("Global Preferences...")); - am->AddAction(ID_GRAPHICS_SETTINGS, tr("&Graphics Settings...")); for (int i = ID_FILE_MRU_FIRST; i <= ID_FILE_MRU_LAST; ++i) { diff --git a/Code/Editor/MainWindow.h b/Code/Editor/MainWindow.h index 34b121537d..99af2ea326 100644 --- a/Code/Editor/MainWindow.h +++ b/Code/Editor/MainWindow.h @@ -249,6 +249,7 @@ private: QPointer m_toolbarCustomizationDialog; QScopedPointer m_sourceControlNotifHandler; + AZ::Event::Handler m_handleImGuiStateChangeHandler; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING static MainWindow* m_instance; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt index 4744b4e174..5aab2a2056 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt @@ -27,6 +27,7 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE 3rdParty::Qt::Core + 3rdParty::Qt::Widgets AZ::AzCore AZ::AzToolsFramework Legacy::CryCommon diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp index c1af8d76d7..a6c1ed6598 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp @@ -66,3 +66,5 @@ namespace EntityOutliner emit OnOptionToggled(DisplayOption::AutoExpand, checked); } } + +#include diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp index 660ea137cf..89cd361fb6 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp @@ -32,7 +32,24 @@ bool OutlinerSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelI bool OutlinerSortFilterProxyModel::lessThan(const QModelIndex& leftIndex, const QModelIndex& rightIndex) const { - return sourceModel()->data(leftIndex).toString() < sourceModel()->data(rightIndex).toString(); + if (leftIndex.isValid() && rightIndex.isValid()) + { + QVariant leftData = sourceModel()->data(leftIndex); + QVariant rightData = sourceModel()->data(rightIndex); + + // make sure to compare the correct data types for sorting the current column + AZ_Assert(leftData.type() == rightData.type(), "OutlinerSortFilterProxyModel::lessThan types do not agree!"); + if (static_cast(leftData.type()) == QMetaType::QString) + { + return leftData.toString() < rightData.toString(); + } + else if (static_cast(leftData.type()) == QMetaType::ULongLong) + { + return leftData.toULongLong() < rightData.toULongLong(); + } + AZ_Error("Editor", false, "Error! Unhandled type \"%s\" in OutlinerSortFilterProxyModel::lessThan", leftData.typeName()); + } + return false; } void OutlinerSortFilterProxyModel::sort(int /*column*/, Qt::SortOrder /*order*/) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp index d69480b169..02dabb8b20 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp @@ -269,10 +269,12 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags) AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect( AzToolsFramework::GetEntityContextId()); AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect(); + AzToolsFramework::EditorWindowUIRequestBus::Handler::BusConnect(); } OutlinerWidget::~OutlinerWidget() { + AzToolsFramework::EditorWindowUIRequestBus::Handler::BusDisconnect(); AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect(); @@ -1321,16 +1323,25 @@ static void SetEntityOutlinerState(Ui::OutlinerWidgetUI* entityOutlinerUi, const AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on); } +void OutlinerWidget::EnableUi(bool enable) +{ + SetEntityOutlinerState(m_gui, enable); + setEnabled(enable); +} + +void OutlinerWidget::SetEditorUiEnabled(bool enable) +{ + EnableUi(enable); +} + void OutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetEntityOutlinerState(m_gui, false); - setEnabled(false); + EnableUi(false); } void OutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - setEnabled(true); - SetEntityOutlinerState(m_gui, true); + EnableUi(true); } void OutlinerWidget::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx index 75991424bb..aff305e0fe 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,7 @@ class OutlinerWidget , private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler , private AzToolsFramework::EditorEntityInfoNotificationBus::Handler , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler + , private AzToolsFramework::EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -106,6 +108,9 @@ private: void EnteredComponentMode(const AZStd::vector& componentModeTypes) override; void LeftComponentMode(const AZStd::vector& componentModeTypes) override; + // EditorWindowUIRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + // Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored. template QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds); @@ -171,6 +176,7 @@ private: AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const; QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const; void ExtractEntityIdsFromSelection(const QItemSelection& selection, AzToolsFramework::EntityIdList& entityIdList) const; + void EnableUi(bool enable); // AzToolsFramework::OutlinerModelNotificationBus::Handler // Receive notification from the outliner model that we should scroll diff --git a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt index 342151f24a..909ec193f3 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt @@ -23,6 +23,7 @@ ly_add_target( . BUILD_DEPENDENCIES PRIVATE + 3rdParty::Qt::Core AZ::AzCore Legacy::CryCommon Legacy::EditorLib diff --git a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h index 3b015dd9a5..33ca3390f1 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h +++ b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h @@ -17,19 +17,8 @@ ///////////////////////////////////////////////////////////////////////////// #include - -///////////////////////////////////////////////////////////////////////////// -// STL -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - ///////////////////////////////////////////////////////////////////////////// // CRY Stuff //////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// #include -#include "Util/EditorUtils.h" #include "EditorCoreAPI.h" diff --git a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt index 15a1147166..bd4661fa0f 100644 --- a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt @@ -31,6 +31,8 @@ ly_add_target( . BUILD_DEPENDENCIES PRIVATE + 3rdParty::Qt::Core + 3rdParty::Qt::Widgets AZ::AzCore Legacy::CryCommon Legacy::EditorLib diff --git a/Code/Editor/QtViewPaneManager.cpp b/Code/Editor/QtViewPaneManager.cpp index 35b2160a1f..9f2b9f9cf8 100644 --- a/Code/Editor/QtViewPaneManager.cpp +++ b/Code/Editor/QtViewPaneManager.cpp @@ -525,6 +525,7 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent) // view pane manager is interested when we enter/exit ComponentMode m_componentModeNotifications.BusConnect(AzToolsFramework::GetEntityContextId()); + m_windowRequest.BusConnect(); m_componentModeNotifications.SetEnteredComponentModeFunc( [this](const AZStd::vector& /*componentModeTypes*/) @@ -545,10 +546,23 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent) AzQtComponents::SetWidgetInteractEnabled(widget, on); }); }); + + m_windowRequest.SetEnableEditorUiFunc( + [this](bool enable) + { + // gray out panels when entering ImGui mode + SetDefaultActionsEnabled( + enable, m_registeredPanes, + [](QWidget* widget, bool on) + { + AzQtComponents::SetWidgetInteractEnabled(widget, on); + }); + }); } QtViewPaneManager::~QtViewPaneManager() { + m_windowRequest.BusDisconnect(); m_componentModeNotifications.BusDisconnect(); } diff --git a/Code/Editor/QtViewPaneManager.h b/Code/Editor/QtViewPaneManager.h index aa382c41c0..2b3412aad6 100644 --- a/Code/Editor/QtViewPaneManager.h +++ b/Code/Editor/QtViewPaneManager.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -249,8 +250,12 @@ private: QPointer m_advancedDockManager; using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl; - EditorComponentModeNotificationBusImpl m_componentModeNotifications; /**< Helper for EditorComponentModeNotificationBus so - * QtViewPaneManager does not need to inherit directly from it. */ + EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so + //!< QtViewPaneManager does not need to inherit directly from it. */ + + using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl; + EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so + //!< QtViewPaneManager does not need to inherit directly from it. */ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; diff --git a/Code/Editor/Resource.h b/Code/Editor/Resource.h index 22bbece700..3ae1024550 100644 --- a/Code/Editor/Resource.h +++ b/Code/Editor/Resource.h @@ -187,7 +187,6 @@ #define ID_SWITCHCAMERA_SEQUENCECAMERA 33701 #define ID_SWITCHCAMERA_SELECTEDCAMERA 33702 #define ID_TV_RECORD_AUTO 33703 -#define ID_GRAPHICS_SETTINGS 33705 #define ID_VIEW_OPENVIEWPANE 33709 #define ID_VIEW_OPENPANE_FIRST 33712 #define ID_VIEW_OPENPANE_LAST 33811 @@ -219,10 +218,6 @@ #define ID_SPLINE_SNAP_GRID_X 33933 #define ID_SPLINE_SNAP_GRID_Y 33934 #define ID_FREEZE_TANGENTS 33935 -#define ID_GAME_PC_ENABLELOWSPEC 33960 -#define ID_GAME_PC_ENABLEMEDIUMSPEC 33961 -#define ID_GAME_PC_ENABLEHIGHSPEC 33962 -#define ID_GAME_PC_ENABLEVERYHIGHSPEC 33963 #define ID_PANEL_VEG_CREATE_SEL 33990 #define ID_TOOLS_UPDATEPROCEDURALVEGETATION 33999 #define ID_DISPLAY_GOTOPOSITION 34004 @@ -287,14 +282,6 @@ #define ID_CLEAR_REGISTRY 34470 #define ID_SOUND_STOPALLSOUNDS 34476 #define ID_AUDIO_REFRESH_AUDIO_SYSTEM 34477 -#define ID_GAME_ANDROID_ENABLELOWSPEC 34490 -#define ID_GAME_ANDROID_ENABLEMEDIUMSPEC 34491 -#define ID_GAME_ANDROID_ENABLEHIGHSPEC 34492 -#define ID_GAME_ANDROID_ENABLEVERYHIGHSPEC 34493 -#define ID_GAME_IOS_ENABLELOWSPEC 34494 -#define ID_GAME_IOS_ENABLEMEDIUMSPEC 34495 -#define ID_GAME_IOS_ENABLEHIGHSPEC 34496 -#define ID_GAME_IOS_ENABLEVERYHIGHSPEC 34497 #define ID_OPEN_AUDIO_CONTROLS_BROWSER 34580 #define ID_CREATE_GLOBAL_FG_MODULE_FROM_SELECTION 35076 #define ID_CREATE_LEVEL_FG_MODULE_FROM_SELECTION 35077 @@ -324,19 +311,6 @@ #define ID_DOCUMENTATION_FEEDBACK 36043 #define ID_OPEN_SUBSTANCE_EDITOR 36060 #define ID_IMPORT_ASSET 36069 -#define ID_GAME_PROVO_ENABLELOWSPEC 34603 -#define ID_GAME_PROVO_ENABLEMEDIUMSPEC 34604 -#define ID_GAME_PROVO_ENABLEHIGHSPEC 34605 -#define ID_GAME_OSXMETAL_ENABLELOWSPEC 34606 -#define ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC 34607 -#define ID_GAME_OSXMETAL_ENABLEHIGHSPEC 34608 -#define ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC 34609 -#define ID_GAME_SALEM_ENABLELOWSPEC 34610 -#define ID_GAME_SALEM_ENABLEMEDIUMSPEC 34611 -#define ID_GAME_SALEM_ENABLEHIGHSPEC 34612 -#define ID_GAME_JASPER_ENABLELOWSPEC 34613 -#define ID_GAME_JASPER_ENABLEMEDIUMSPEC 34614 -#define ID_GAME_JASPER_ENABLEHIGHSPEC 34615 #define ID_FILE_RESAVESLICES 36210 #define FIRST_QT_ACTION 50000 #define ID_VIEW_CONSOLEWINDOW 50001 diff --git a/Code/Editor/Style/GraphicsSettingsDialog.qss b/Code/Editor/Style/GraphicsSettingsDialog.qss deleted file mode 100644 index 3af8c4c05b..0000000000 --- a/Code/Editor/Style/GraphicsSettingsDialog.qss +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#GraphicsSettingsDialog QHeaderView::section -{ - background: #2D2D2D; -} - -#GraphicsSettingsDialog QHeaderView::down-arrow -{ - width: 14px; - height: 14px; - image: url(:/Gallery/Delete.svg); -} - -#GraphicsSettingsDialog QHeaderView::up-arrow -{ - width: 14px; - height: 14px; - image: url(:/Gallery/Delete.svg); -} diff --git a/Code/Editor/Style/resources.qrc b/Code/Editor/Style/resources.qrc index aec7e2cf68..24682d2be3 100644 --- a/Code/Editor/Style/resources.qrc +++ b/Code/Editor/Style/resources.qrc @@ -3,6 +3,5 @@ Editor.qss EditorPreferencesDialog.qss LayoutConfigDialog.qss - GraphicsSettingsDialog.qss diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp index f9560aef55..49d9c58159 100644 --- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp +++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp @@ -40,10 +40,6 @@ #include "CryEdit.h" #include "LevelFileDialog.h" -// NewsShared -#include // for News::ResourceManifest -#include // for News::ArticleViewContainer - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h index 4338a8250f..39c0ad6316 100644 --- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h +++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h @@ -8,8 +8,6 @@ #if !defined(Q_MOC_RUN) #include -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" #endif namespace News { @@ -62,9 +60,6 @@ private: void OnRecentLevelTableItemClicked(const QModelIndex& index); void OnCloseBtnClicked(bool checked); - void SyncFail(News::ErrorCode error); - void SyncSuccess(); - private Q_SLOTS: void previewAreaScrolled(); }; diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index fc1694240e..3181474b35 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -583,9 +583,6 @@ set(FILES SettingsManager.h SettingsManagerDialog.h SettingsManagerDialog.ui - GraphicsSettingsDialog.h - GraphicsSettingsDialog.cpp - graphicssettingsdialog.ui AboutDialog.cpp ErrorReportTableModel.h ErrorReportTableModel.cpp diff --git a/Code/Editor/graphicssettingsdialog.ui b/Code/Editor/graphicssettingsdialog.ui deleted file mode 100644 index ca8770e9e3..0000000000 --- a/Code/Editor/graphicssettingsdialog.ui +++ /dev/null @@ -1,270 +0,0 @@ - - - GraphicsSettingsDialog - - - - 0 - 0 - 1292 - 565 - - - - - 0 - 0 - - - - - 800 - 400 - - - - - 16777215 - 16777215 - - - - Graphics Settings - - - - - - - 0 - - - 6 - - - - - - 0 - 0 - - - - - 0 - 20 - - - - - 16777215 - 20 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - 100 - 0 - - - - - 16777215 - 20 - - - - Add Resource - - - - - - - - 0 - 0 - - - - - 60 - 20 - - - - Platform - - - Qt::AlignCenter - - - - - - - - 13 - 0 - - - - Qt::Vertical - - - - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 1272 - 452 - - - - - 0 - 0 - - - - - - - - 0 - 0 - - - - 8 - - - false - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - background-color: rgb(233, 118, 17); - - - Save - - - - - - - - 0 - 0 - - - - Cancel - - - - - - - - - Qt::Horizontal - - - - - line - m_scrollArea - line_2 - widget - - - - GraphicsSettingsTreeView - QTreeView -
GraphicsSettingsDialog.h
-
-
- - m_cancelButton - m_applyButton - m_scrollArea - - - -
diff --git a/Code/Framework/AzCore/AzCore/EBus/Event.inl b/Code/Framework/AzCore/AzCore/EBus/Event.inl index 006ff81e34..493dea4a3f 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Event.inl +++ b/Code/Framework/AzCore/AzCore/EBus/Event.inl @@ -27,11 +27,17 @@ namespace AZ template EventHandler::EventHandler(const EventHandler& rhs) : m_callback(rhs.m_callback) + , m_event(rhs.m_event) { - // Copy the callback function, then perform a Connect with the new event - if (rhs.m_event) + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) { - rhs.m_event->Connect(*this); + m_event->Connect(*this); + } + else + { + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } @@ -65,9 +71,16 @@ namespace AZ { Disconnect(); m_callback = rhs.m_callback; - if (rhs.m_event) + m_event = rhs.m_event; + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) { - rhs.m_event->Connect(*this); + m_event->Connect(*this); + } + else + { + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp index efbc0eaa1f..5a709f9324 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp @@ -32,6 +32,15 @@ namespace AZ { if (m_hashes.size() < m_hashes.max_size()) { + constexpr size_t MaxTagSize = TagName{}.max_size(); + if (specialization.size() > MaxTagSize) + { + AZ_Error("Settings Registry", false, R"(Cannot append Specialization tag of "%.*s.")" + " It is longer than the MaxTagNameSize of %zu", AZ_STRING_ARG(specialization), + MaxTagSize); + return false; + } + m_names.push_back(TagName{ specialization }); TagName& tag = m_names.back(); AZStd::to_lower(tag.begin(), tag.end()); diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h index baeca89636..f0077db2ca 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h @@ -49,7 +49,7 @@ namespace AZ class Specializations { public: - static constexpr size_t MaxTagNameSize = 32; + static constexpr size_t MaxTagNameSize = 64; static constexpr size_t MaxCount = 15; static constexpr size_t NotFound = static_cast(-1); using TagName = AZStd::fixed_string; diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 9b2ccbe754..39f6c02bde 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -146,7 +146,7 @@ namespace AZ { AZStd::mutex g_dbgLoadingMutex; HANDLE g_currentProcess = 0; /// We deal with only one process for now. CRITICAL_SECTION g_csDbgHelpDll; /// All dbg help functions are single threaded, so we need to control the access. - AZStd::fixed_vector g_moduleInfo; + AZStd::fixed_vector g_moduleInfo; // reserve 4k of scratch space so that we can get some callstack information without any allocations and as little stack frame usage as possible. const size_t g_scratchSpaceSize = 2048; diff --git a/Code/Framework/AzCore/Tests/EventTests.cpp b/Code/Framework/AzCore/Tests/EventTests.cpp index 7640201e0d..571bdd5345 100644 --- a/Code/Framework/AzCore/Tests/EventTests.cpp +++ b/Code/Framework/AzCore/Tests/EventTests.cpp @@ -257,6 +257,48 @@ namespace UnitTest EXPECT_FALSE(testEvent1.HasHandlerConnected()); EXPECT_TRUE(testEvent2.HasHandlerConnected()); } + + TEST_F(EventTests, TestHandlerCopyConstructorOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2(testHandler); + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } + + TEST_F(EventTests, TestHandlerCopyAssignmentOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2; + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_FALSE(testHandler2.IsConnected()); + + testHandler2 = testHandler; + + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } } #if defined(HAVE_BENCHMARK) diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h index 98893e2d01..2cf5b3f87e 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h @@ -12,5 +12,5 @@ #define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 1 #define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 0 #define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh" -#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0 +#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1 #define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0 diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h index 6af4294a5c..73f6d212d4 100644 --- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h +++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h @@ -12,5 +12,5 @@ #define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 0 #define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 1 #define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh" -#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0 +#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1 #define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0 diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp index 130739ca39..651eff820e 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp @@ -41,7 +41,7 @@ namespace AzNetworking void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback) { - if(static_cast(m_maxFd) <= 0 && m_socketFds.empty()) + if(static_cast(m_maxFd) <= 0 || m_socketFds.empty()) { // There are no available sockets to process return; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h index 03bb76b03a..ef4d2deb5e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h @@ -36,8 +36,47 @@ namespace AzToolsFramework /// Retrieve the main application window. virtual QWidget* GetAppMainWindow() { return nullptr; } }; - using EditorWindowRequestBus = AZ::EBus; + + class EditorWindowUIRequests : public AZ::EBusTraits + { + public: + using Bus = AZ::EBus; + + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + ////////////////////////////////////////////////////////////////////////// + + /// Enable/Disable the Editor UI. + virtual void SetEditorUiEnabled([[maybe_unused]] bool enable) {} + }; + using EditorWindowUIRequestBus = AZ::EBus; + + using EnableUiFunction = AZStd::function; + + /// Helper for EditorWindowRequests to be used as a + /// member instead of inheriting from EBus directly. + class EditorWindowRequestBusImpl + : public EditorWindowUIRequestBus::Handler + { + public: + /// Set the function to be called when entering ImGui Mode. + void SetEnableEditorUiFunc(const EnableUiFunction enableEditorUiFunc) + { + m_enableEditorUiFunc = AZStd::move(enableEditorUiFunc); + } + + private: + // EditorWindowRequestBus + void SetEditorUiEnabled( [[maybe_unused]] bool enable) override + { + m_enableEditorUiFunc(enable); + } + + EnableUiFunction m_enableEditorUiFunc; ///< Function to call when entering ImGui Mode. + }; + } // namespace AzToolsFramework #endif // AZTOOLSFRAMEWORK_EDITORWINDOWREQUESTBUS_H diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp index 73139b5a67..90274bc734 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp @@ -34,7 +34,24 @@ namespace AzToolsFramework bool EntityOutlinerSortFilterProxyModel::lessThan(const QModelIndex& leftIndex, const QModelIndex& rightIndex) const { - return sourceModel()->data(leftIndex).toString() < sourceModel()->data(rightIndex).toString(); + if (leftIndex.isValid() && rightIndex.isValid()) + { + QVariant leftData = sourceModel()->data(leftIndex); + QVariant rightData = sourceModel()->data(rightIndex); + + // make sure to compare the correct data types for sorting the current column + AZ_Assert(leftData.type() == rightData.type(), "EntityOutlinerSortFilterProxyModel::lessThan types do not agree!"); + if (static_cast(leftData.type()) == QMetaType::QString) + { + return leftData.toString() < rightData.toString(); + } + else if (static_cast(leftData.type()) == QMetaType::ULongLong) + { + return leftData.toULongLong() < rightData.toULongLong(); + } + AZ_Error("Editor", false, "Error! Unhandled type \"%s\" in EntityOutlinerSortFilterProxyModel::lessThan", leftData.typeName()); + } + return false; } void EntityOutlinerSortFilterProxyModel::sort(int /*column*/, Qt::SortOrder /*order*/) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp index 96479bb54c..03784343f5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp @@ -291,10 +291,12 @@ namespace AzToolsFramework GetEntityContextId()); EditorEntityInfoNotificationBus::Handler::BusConnect(); Prefab::PrefabPublicNotificationBus::Handler::BusConnect(); + EditorWindowUIRequestBus::Handler::BusConnect(); } EntityOutlinerWidget::~EntityOutlinerWidget() { + EditorWindowUIRequestBus::Handler::BusDisconnect(); Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); EditorEntityInfoNotificationBus::Handler::BusDisconnect(); @@ -1106,16 +1108,25 @@ namespace AzToolsFramework AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on); } + void EntityOutlinerWidget::EnableUi(bool enable) + { + SetEntityOutlinerState(m_gui, enable); + setEnabled(enable); + } + + void EntityOutlinerWidget::SetEditorUiEnabled(bool enable) + { + EnableUi(enable); + } + void EntityOutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetEntityOutlinerState(m_gui, false); - setEnabled(false); + EnableUi(false); } void EntityOutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - setEnabled(true); - SetEntityOutlinerState(m_gui, true); + EnableUi(true); } void EntityOutlinerWidget::OnPrefabInstancePropagationBegin() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx index 68f538c3ff..e3f9ad2135 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,7 @@ namespace AzToolsFramework , private EditorEntityInfoNotificationBus::Handler , private ComponentModeFramework::EditorComponentModeNotificationBus::Handler , private Prefab::PrefabPublicNotificationBus::Handler + , private EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -105,6 +107,9 @@ namespace AzToolsFramework void OnPrefabInstancePropagationBegin() override; void OnPrefabInstancePropagationEnd() override; + // EditorWindowUIRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + // Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored. template QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds); @@ -155,6 +160,7 @@ namespace AzToolsFramework AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const; QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const; void ExtractEntityIdsFromSelection(const QItemSelection& selection, EntityIdList& entityIdList) const; + void EnableUi(bool enable); // OutlinerModelNotificationBus::Handler // Receive notification from the outliner model that we should scroll diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 6a399ad816..5d1ec93fda 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -376,6 +376,7 @@ namespace AzToolsFramework ToolsApplicationEvents::Bus::Handler::BusConnect(); AZ::EntitySystemBus::Handler::BusConnect(); EntityPropertyEditorRequestBus::Handler::BusConnect(); + EditorWindowUIRequestBus::Handler::BusConnect(); m_spacer = nullptr; m_emptyIcon = QIcon(); @@ -421,6 +422,7 @@ namespace AzToolsFramework { qApp->removeEventFilter(this); + EditorWindowUIRequestBus::Handler::BusDisconnect(); EntityPropertyEditorRequestBus::Handler::BusDisconnect(); ToolsApplicationEvents::Bus::Handler::BusDisconnect(); AZ::EntitySystemBus::Handler::BusDisconnect(); @@ -4961,6 +4963,27 @@ namespace AzToolsFramework EnableDisableComponentActions(widget, actions, false); } + void EntityPropertyEditor::SetEditorUiEnabled(bool enable) + { + if (enable) + { + EnableComponentActions(this, m_entityComponentActions); + } + else + { + DisableComponentActions(this, m_entityComponentActions); + } + m_disabled = !enable; + SetPropertyEditorState(m_gui, enable); + + for (auto componentEditor : m_componentEditors) + { + AzQtComponents::SetWidgetInteractEnabled(componentEditor, enable); + } + // record the selected state after entering/leaving component mode + SaveComponentEditorState(); + } + void EntityPropertyEditor::EnteredComponentMode(const AZStd::vector& componentModeTypes) { DisableComponentActions(this, m_entityComponentActions); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx index b15e27e41a..f2ff4eb927 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,7 @@ namespace AzToolsFramework , public EditorInspectorComponentNotificationBus::MultiHandler , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler , public AZ::EntitySystemBus::Handler + , private EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -208,6 +210,9 @@ namespace AzToolsFramework void GetSelectedEntities(EntityIdList& selectedEntityIds) override; void SetNewComponentId(AZ::ComponentId componentId) override; + // EditorWindowRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + bool IsEntitySelected(const AZ::EntityId& id) const; bool IsSingleEntitySelected(const AZ::EntityId& id) const; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h index d9bf0c40b9..e08bb13cac 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h @@ -22,11 +22,11 @@ namespace AzToolsFramework /// @name Reverse URLs. /// Used to identify common actions and override them when necessary. //@{ - static const AZ::Crc32 s_backAction = AZ_CRC("com.amazon.action.common.back", 0xd772a2af); - static const AZ::Crc32 s_deleteAction = AZ_CRC("com.amazon.action.common.delete", 0x5731f6cb); - static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.amazon.action.common.duplicate", 0x08ccf461); - static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.amazon.action.common.nextComponentMode", 0xcc26094f); - static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.amazon.action.common.previousComponentMode", 0x0d18ff39); + static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af); + static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb); + static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461); + static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f); + static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39); //@} /// Specific Action properties to be sent to a type implementing diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h index f92ee6b00b..73be188f2c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h @@ -98,7 +98,7 @@ namespace AzToolsFramework { } - AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---"). + AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.o3de.action.---"). AZStd::vector> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections //!< there will be a callback per Entity/Component). AZStd::unique_ptr m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions. diff --git a/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp index caf6411eda..844fbb3e7f 100644 --- a/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp @@ -196,7 +196,7 @@ namespace AzToolsFramework AZStd::vector PlaceHolderComponentMode::PopulateActionsImpl() { - const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.amazon.action.placeholder.test"); + const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.o3de.action.placeholder.test"); return AZStd::vector { diff --git a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp index 97802a1516..d92b72e11a 100644 --- a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp +++ b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp @@ -25,6 +25,8 @@ namespace AWSNativeSDKInit #if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK) void CustomizeSDKOptions(Aws::SDKOptions& options); void CustomizeShutdown(); + + void CopyCaCertBundle(); #endif } @@ -44,6 +46,8 @@ namespace AWSNativeSDKInit void InitializationManager::InitAwsApi() { s_initManager = AZ::Environment::CreateVariable(initializationManagerTag); + + Platform::CopyCaCertBundle(); } void InitializationManager::Shutdown() diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp new file mode 100644 index 0000000000..67cdee7edc --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING +#include +#include +#include +#include + +namespace AWSNativeSDKInit +{ + namespace Platform + { + void CopyCaCertBundle() + { + AZStd::vector contents; + AZStd::string certificatePath = "@assets@/certificates/aws/cacert.pem"; + AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath(); + publicStoragePath.append("/certificates/aws/cacert.pem"); + + AZ::IO::FileIOBase* fileBase = AZ::IO::FileIOBase::GetInstance(); + + if (!fileBase->Exists(certificatePath.c_str())) + { + AZ_Error("AWSNativeSDKInit", false, "Certificate File(%s) does not exist.\n", certificatePath.c_str()); + } + + AZ::IO::HandleType fileHandle; + AZ::IO::Result fileResult = fileBase->Open(certificatePath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle); + + if (!fileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to open certificate file with result %i\n", fileResult.GetResultCode()); + } + + AZ::u64 fileSize = 0; + fileBase->Size(fileHandle, fileSize); + + if (fileSize == 0) + { + AZ_Error("AWSNativeSDKInit", false, "Given empty file(%s) as the certificate bundle.\n", certificatePath.c_str()); + } + + contents.resize(fileSize + 1); + fileResult = fileBase->Read(fileHandle, contents.data(), fileSize); + + if (!fileResult) + { + AZ_Error( + "AWSNativeSDKInit", false, "Failed to read from the certificate bundle(%s) with result code(%i).\n", certificatePath.c_str(), + fileResult.GetResultCode()); + } + + AZ_Printf("AWSNativeSDKInit", "Certificate bundle is read successfully from %s", certificatePath.c_str()); + + AZ::IO::HandleType outFileHandle; + + AZ::IO::Result outFileResult = fileBase->Open(publicStoragePath.c_str(), AZ::IO::OpenMode::ModeWrite, outFileHandle); + + if (!outFileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to open the certificate bundle with result %i\n", fileResult.GetResultCode()); + } + + AZ::IO::Result writeFileResult = fileBase->Write(outFileHandle, contents.data(), fileSize); + if (!writeFileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to write the certificate bundle with result %i\n", writeFileResult.GetResultCode()); + } + + fileBase->Close(fileHandle); + fileBase->Close(outFileHandle); + + AZ_Printf("AWSNativeSDKInit", "Certificate bundle successfully copied to %s", publicStoragePath.c_str()); + } + } // namespace Platform +} diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake index 0ec1f30fea..6e0370dd42 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + InitializeCerts_Android.cpp ) diff --git a/Code/Tools/News/NewsShared/LogType.h b/Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp similarity index 56% rename from Code/Tools/News/NewsShared/LogType.h rename to Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp index 92834adc58..7981998327 100644 --- a/Code/Tools/News/NewsShared/LogType.h +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp @@ -1,18 +1,16 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace News { - enum LogType - { - LogOk, - LogInfo, - LogError, - LogWarning - }; -} // namespace News +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +namespace AWSNativeSDKInit +{ + namespace Platform + { + void CopyCaCertBundle() + { + } + } // namespace Platform +} // namespace AWSCore diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp b/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp index 2ffe6a7996..dd39283b22 100644 --- a/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp +++ b/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -277,7 +277,7 @@ void FileWatcherUnitTestRunner::StartTest() UNIT_TEST_EXPECT_TRUE(QDir::toNativeSeparators(fileAddName).toLower() == QDir::toNativeSeparators(newName3).toLower()); #if !defined(AZ_PLATFORM_LINUX) - // final test... make sure that renaming a DIRECTORY works too. + // final test... make sure that renaming a DIRECTORY works too. // Note that linux does not get any callbacks if just the directory is renamed (from inotify) QDir renamer; fileAddCalled = false; @@ -312,6 +312,9 @@ void FileWatcherUnitTestRunner::StartTest() Q_EMIT UnitTestPassed(); } -#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS +// File operations on Linux behave differently on Linux than Windows. +// The system under test doesn't yet handle Linux's file operations, which surfaced as this test arbitrarily passing and failing. +// This test is disabled on Linux until the system under test can handle Linux file system behavior correctly. +#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS && !defined(AZ_PLATFORM_LINUX) REGISTER_UNIT_TEST(FileWatcherUnitTestRunner) #endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS diff --git a/Code/Tools/CMakeLists.txt b/Code/Tools/CMakeLists.txt index 6c025a0543..1bab1cee77 100644 --- a/Code/Tools/CMakeLists.txt +++ b/Code/Tools/CMakeLists.txt @@ -10,7 +10,6 @@ add_subdirectory(AssetProcessor) add_subdirectory(AWSNativeSDKInit) add_subdirectory(AzTestRunner) add_subdirectory(CrashHandler) -add_subdirectory(News) add_subdirectory(PythonBindingsExample) add_subdirectory(RemoteConsole) add_subdirectory(DeltaCataloger) diff --git a/Code/Tools/News/CMakeLists.txt b/Code/Tools/News/CMakeLists.txt deleted file mode 100644 index 78c5774ef0..0000000000 --- a/Code/Tools/News/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(NewsBuilder) - -if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_add_target( - NAME NewsShared STATIC - NAMESPACE Legacy - AUTOMOC - AUTOUIC - AUTORCC - FILES_CMAKE - news_shared_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Network - 3rdParty::Qt::Widgets - AZ::AzQtComponents -) diff --git a/Code/Tools/News/NewsBuilder/CMakeLists.txt b/Code/Tools/News/NewsBuilder/CMakeLists.txt deleted file mode 100644 index 218f4e28f5..0000000000 --- a/Code/Tools/News/NewsBuilder/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - -include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) - -if (NOT PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_add_target( - NAME NewsBuilder EXECUTABLE - NAMESPACE Legacy - AUTOMOC - AUTOUIC - AUTORCC - FILES_CMAKE - news_builder_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Widgets - 3rdParty::AWSNativeSDK::Dependencies - 3rdParty::AWSNativeSDK::Core - 3rdParty::AWSNativeSDK::S3 - Legacy::NewsShared - AZ::AzCore - AZ::AzQtComponents - AZ::AzFramework -) diff --git a/Code/Tools/News/NewsBuilder/EndpointManager.cpp b/Code/Tools/News/NewsBuilder/EndpointManager.cpp deleted file mode 100644 index 0b2ea4dd5c..0000000000 --- a/Code/Tools/News/NewsBuilder/EndpointManager.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointManager.h" -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace News -{ - - Endpoint::Endpoint(QString name, QString awsProfile, QString url, QString bucket) - : m_name(name) - , m_awsProfile(awsProfile) - , m_url(url) - , m_bucket(bucket) - {} - - Endpoint::Endpoint(const QJsonObject& json) - : Endpoint(json["name"].toString(), - json["awsProfile"].toString(), - json["url"].toString(), - json["bucket"].toString()) - { - } - - Endpoint::~Endpoint() {} - - void Endpoint::Write(QJsonObject& json) const - { - json["name"] = m_name; - json["awsProfile"] = m_awsProfile; - json["url"] = m_url; - json["bucket"] = m_bucket; - } - - QString Endpoint::GetName() const - { - return m_name; - } - - void Endpoint::SetName(const QString& name) - { - m_name = QString(name); - } - - QString Endpoint::GetAwsProfile() const - { - return m_awsProfile; - } - - void Endpoint::SetAwsProfile(const QString& awsProfile) - { - m_awsProfile = QString(awsProfile); - } - - QString Endpoint::GetUrl() const - { - return m_url; - } - - void Endpoint::SetUrl(const QString& url) - { - m_url = QString(url); - } - - QString Endpoint::GetBucket() const - { - return m_bucket; - } - - void Endpoint::SetBucket(const QString& bucket) - { - m_bucket = bucket; - } - - EndpointManager::EndpointManager() - { - Load(); - } - - EndpointManager::~EndpointManager() - { - ClearEndpoints(); - } - - void EndpointManager::Load() - { - ClearEndpoints(); - QFile file("newsBuilderConfig.txt"); - if (file.open(QIODevice::ReadOnly)) - { - QTextStream in(&file); - QString str = in.readAll().trimmed(); - QByteArray array(str.toStdString().c_str()); - QJsonDocument doc(QJsonDocument::fromJson(array)); - QJsonObject json = doc.object(); - QJsonArray endpointArray = json["endpoints"].toArray(); - for (auto endpointDoc : endpointArray) - { - m_endpoints.append(new Endpoint(endpointDoc.toObject())); - } - int endpointIndex = json["currentEndpointIndex"].toInt(); - if (endpointIndex >= 0 && m_endpoints.count() > endpointIndex) - { - m_selectedEndpoint = m_endpoints[endpointIndex]; - } - else - { - m_selectedEndpoint = nullptr; - } - file.close(); - - SaveUrl(); - } - } - - void EndpointManager::Save() - { - QFile file("newsBuilderConfig.txt"); - if (file.open(QIODevice::WriteOnly)) - { - QJsonObject json; - QJsonArray endpointArray; - for (auto endpoint : m_endpoints) - { - QJsonObject endpointObject; - endpoint->Write(endpointObject); - endpointArray.append(endpointObject); - } - json["endpoints"] = endpointArray; - json["currentEndpointIndex"] = m_endpoints.indexOf(m_selectedEndpoint); - QTextStream out(&file); - QJsonDocument doc(json); - out << doc.toJson(QJsonDocument::Compact); - file.close(); - - SaveUrl(); - } - } - - void EndpointManager::SelectEndpoint(Endpoint* endpoint) - { - m_selectedEndpoint = endpoint; - } - - void EndpointManager::AddEndpoint(Endpoint* endpoint) - { - m_endpoints.append(endpoint); - } - - void EndpointManager::RemoveEndpoint(Endpoint* endpoint) - { - if (endpoint == m_selectedEndpoint) - { - m_selectedEndpoint = nullptr; - } - m_endpoints.removeAll(endpoint); - delete endpoint; - } - - Endpoint* EndpointManager::GetSelectedEndpoint() const - { - return m_selectedEndpoint; - } - - QList::const_iterator EndpointManager::begin() const - { - return m_endpoints.begin(); - } - - QList::const_iterator EndpointManager::end() const - { - return m_endpoints.end(); - } - - void EndpointManager::ClearEndpoints() - { - for (auto endpoint : m_endpoints) - { - delete endpoint; - } - m_endpoints.clear(); - } - - void EndpointManager::SaveUrl() const - { - if (!m_selectedEndpoint) - { - return; - } - // Editor looks for config file in /dev folder, so this file is placed in parent directory - QFile file(QCoreApplication::applicationDirPath() + "/newsConfig.txt"); - if (file.open(QIODevice::WriteOnly)) - { - QTextStream out(&file); - out << m_selectedEndpoint->GetUrl(); - file.close(); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/EndpointManager.h b/Code/Tools/News/NewsBuilder/EndpointManager.h deleted file mode 100644 index cc44951d16..0000000000 --- a/Code/Tools/News/NewsBuilder/EndpointManager.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -class QJsonObject; - -namespace News -{ - //! Endpoint represents a location of news data - class Endpoint - { - public: - Endpoint(QString name, QString awsProfile, QString url, QString bucket); - explicit Endpoint(const QJsonObject& json); - ~Endpoint(); - - void Write(QJsonObject& json) const; - - QString GetName() const; - void SetName(const QString& name); - - QString GetAwsProfile() const; - void SetAwsProfile(const QString& awsProfile); - - QString GetUrl() const; - void SetUrl(const QString& url); - - QString GetBucket() const; - void SetBucket(const QString& bucket); - - private: - //! name of endpoint to distinguish with others - QString m_name; - //! name of aws credentials file - QString m_awsProfile; - //! url location of news data (e.g. cloudfront url) - QString m_url; - //! name of s3 bucket where news data resides - QString m_bucket; - }; - - //! EndpointManager handles endpoint collection - class EndpointManager - { - public: - EndpointManager(); - ~EndpointManager(); - - //! Load endpoints file - void Load(); - //! Save endpoints file - void Save(); - void SelectEndpoint(Endpoint* endpoint); - void AddEndpoint(Endpoint* endpoint); - void RemoveEndpoint(Endpoint* endpoint); - Endpoint* GetSelectedEndpoint() const; - - QList::const_iterator begin() const; - QList::const_iterator end() const; - - private: - QList m_endpoints; - Endpoint* m_selectedEndpoint = nullptr; - - void ClearEndpoints(); - //! Saves news config file which is used by LY Editor to determine news location - void SaveUrl() const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake b/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake deleted file mode 100644 index 929d864fc4..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp deleted file mode 100644 index 2872a714e8..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDetails.h" -#include "SelectImage.h" -#include -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ResourceManagement/ImageDescriptor.h" -#include "NewsShared/ErrorCodes.h" - -#include - -#include -#include -#include -#include - -#include "Qt/ui_ArticleDetails.h" - -namespace News -{ - - ArticleDetails::ArticleDetails(QWidget* parent, - Resource& resource, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleDetailsWidget) - , m_filename("") - , m_article(resource) - , m_manifest(manifest) - , m_imageIdOriginal("") - , m_imageId("") - { - m_ui->setupUi(this); - m_ui->uidLabel->setText(QString("Article: %1").arg(m_article.GetResource().GetId())); - - resizePreviewImage(); - - //! try to load image icon - auto pImageResource = m_manifest.FindById(m_article.GetImageId()); - if (pImageResource) - { - m_imageIdOriginal = pImageResource->GetId(); - SetImage(*pImageResource); - } - else - { - SetNoImage(); - } - - m_ui->titleText->setText(m_article.GetTitle()); - m_ui->descriptionText->setPlainText(m_article.GetBody()); - - connect(m_ui->fromFileButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromFile); - connect(m_ui->fromResourceButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromResource); - connect(m_ui->clearImageButton, &QPushButton::clicked, this, &ArticleDetails::ClearImage); - connect(m_ui->updateButton, &QPushButton::clicked, this, &ArticleDetails::UpdateArticle); - connect(m_ui->deleteButton, &QPushButton::clicked, this, &ArticleDetails::DeleteArticle); - connect(m_ui->cancelButton, &QPushButton::clicked, this, &ArticleDetails::Close); - connect(m_ui->upButton, &QPushButton::clicked, this, &ArticleDetails::MoveUp); - connect(m_ui->downButton, &QPushButton::clicked, this, &ArticleDetails::MoveDown); - } - - ArticleDetails::~ArticleDetails() {} - - void ArticleDetails::resizeEvent(QResizeEvent *event) - { - QWidget::resizeEvent(event); - resizePreviewImage(); - } - - void ArticleDetails::resizePreviewImage() - { - // Resize the imagePreview to keep the proportions - int newHeight = aznumeric_cast(m_imageRatio * width()); - m_ui->imagePreview->setFixedHeight(newHeight); - } - - ArticleDescriptor& ArticleDetails::GetArticle() - { - return m_article; - } - - QString ArticleDetails::GetId() const - { - return m_article.GetResource().GetId(); - } - - void ArticleDetails::OpenImageFromFile() - { - m_filename = QFileDialog::getOpenFileName(this, - "Open Image", ".", "Image Files (*.png *.jpg *.bmp)"); - SetImage(m_filename); - } - - void ArticleDetails::OpenImageFromResource() - { - m_pSelectImage = new SelectImage(m_manifest); - if (m_pSelectImage->exec() == QDialog::DialogCode::Accepted) - { - auto pSelectedResource = m_pSelectImage->GetSelected(); - if (!pSelectedResource) - { - QMessageBox msgBox(QMessageBox::Critical, - "Error", - "No resource pSelectedResource", - QMessageBox::Ok, - this); - msgBox.exec(); - return; - } - SetImage(*pSelectedResource); - } - delete m_pSelectImage; - } - - //! once the Update button is clicked, article resource is updated in this function - void ArticleDetails::UpdateArticle() - { - //! this flag remains false if no new changes are detected, thus avoiding unnecessary - //! re-uploading unchanged resources - bool updated = false; - - m_imageId = LoadImage(); - if (m_imageId.compare(m_imageIdOriginal) != 0) - { - m_article.SetImageId(m_imageId); - m_filename = ""; - m_imageIdOriginal = m_imageId; - m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_imageId)); - updated = true; - } - - QString newTitle = m_ui->titleText->text(); - if (m_article.GetTitle().compare(newTitle)) - { - m_article.SetTitle(newTitle); - updated = true; - } - QString newBody = m_ui->descriptionText->toPlainText(); - if (m_article.GetBody().compare(newBody) != 0) - { - m_article.SetBody(newBody); - updated = true; - } - - QString newStyle = m_ui->articleStyleButtonGroup->checkedButton()->property("style").toString(); - if (m_article.GetArticleStyle() != newStyle) - { - m_article.SetArticleStyle(newStyle); - updated = true; - } - - if (updated) - { - m_article.Update(); - m_manifest.UpdateResource(&m_article.GetResource()); - emit logSignal(QString("Article %1 updated") - .arg(m_article.GetResource().GetId()), LogOk); - } - else - { - emit logSignal("Nothing to update", LogWarning); - } - emit updateArticleSignal(); - } - - //! try to load an image either from filename or from another resource, - //! update resource manifest accordingly - QString ArticleDetails::LoadImage() const - { - if (!m_filename.isEmpty()) - { - if (!m_imageIdOriginal.isEmpty()) - { - m_manifest.FreeResource(m_imageIdOriginal); - } - auto pResource = m_manifest.AddImage(m_filename); - if (pResource) - { - return pResource->GetId(); - } - return ""; - } - - if (m_imageId.compare(m_imageIdOriginal) != 0) - { - if (!m_imageIdOriginal.isEmpty()) - { - m_manifest.FreeResource(m_imageIdOriginal); - } - if (!m_imageId.isEmpty()) - { - m_manifest.UseResource(m_imageId); - } - return m_imageId; - } - - return m_imageIdOriginal; - } - - void ArticleDetails::SetImage(Resource& resource) - { - m_ui->imagePathLabel->setText(QString("Image: %1").arg(resource.GetId())); - - QPixmap pixmap; - if (pixmap.loadFromData(resource.GetData())) - { - m_ui->imagePreview->setPixmap(pixmap); - m_imageId = resource.GetId(); - } - else - { - SetNoImage(); - emit logSignal(QString("Failed to load image: %1.").arg(m_imageId)); - } - } - - void ArticleDetails::SetImage([[maybe_unused]] QString& filename) - { - m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_filename)); - - QPixmap pixmap; - if (pixmap.load(m_filename)) - { - m_ui->imagePreview->setPixmap(pixmap); - } - else - { - SetNoImage(); - emit logSignal(QString("Failed to load image: %1.").arg(m_filename)); - } - } - - void ArticleDetails::SetNoImage() const - { - m_ui->imagePreview->setPixmap(QPixmap(":/images/Resources/missing-image.png")); - m_ui->imagePathLabel->setText("no image"); - } - - void ArticleDetails::ClearImage() - { - m_imageId = ""; - m_filename = ""; - SetNoImage(); - } - - void ArticleDetails::DeleteArticle() - { - if (!m_article.GetImageId().isEmpty()) - { - m_manifest.FreeResource(m_article.GetImageId()); - } - m_manifest.FreeResource(m_article.GetResource().GetId()); - emit deleteArticleSignal(); - } - - void ArticleDetails::Close() - { - emit closeArticleSignal(); - } - - void ArticleDetails::MoveUp() - { - ErrorCode error; - if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 1, error)) - { - emit logSignal(GetErrorMessage(error)); - } - else - { - emit orderChangedSignal(m_article.GetResource().GetId(), 1); - } - } - - void ArticleDetails::MoveDown() - { - ErrorCode error; - if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 0, error)) - { - emit logSignal(GetErrorMessage(error)); - } - else - { - emit orderChangedSignal(m_article.GetResource().GetId(), 0); - } - } - -#include "Qt/moc_ArticleDetails.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h deleted file mode 100644 index 7f8d482e3f..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include "ResourceManagement/BuilderResourceManifest.h" - -#include -#endif - -namespace Ui -{ - class ArticleDetailsWidget; -} - -namespace News { - class SelectImage; - class ResourceManifest; - class Resource; - - //! Control that allows to modify all parameters of a single article - class ArticleDetails - : public QWidget - { - Q_OBJECT - - public: - ArticleDetails(QWidget* parent, - Resource& resource, - BuilderResourceManifest& manifest); - ~ArticleDetails(); - ArticleDescriptor& GetArticle(); - QString GetId() const; - - Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void deleteArticleSignal(); - void updateArticleSignal(); - void closeArticleSignal(); - void orderChangedSignal(QString id, bool direction); - - private: - QScopedPointer m_ui; - QString m_filename; - ArticleDescriptor m_article; - BuilderResourceManifest& m_manifest; - SelectImage* m_pSelectImage; - QString m_imageIdOriginal; - QString m_imageId; - float m_imageRatio = 184.0f / 430.0f; - - void resizeEvent(QResizeEvent *event) override; - void resizePreviewImage(); - - void OpenImageFromFile(); - void OpenImageFromResource(); - QString LoadImage() const; - void SetImage(Resource& resource); - void SetImage(QString& filename); - void SetNoImage() const; - void ClearImage(); - - void UpdateArticle(); - void DeleteArticle(); - void Close(); - void MoveUp(); - void MoveDown(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui deleted file mode 100644 index 92970f1130..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui +++ /dev/null @@ -1,406 +0,0 @@ - - - ArticleDetailsWidget - - - - 0 - 0 - 250 - 420 - - - - - 0 - 0 - - - - - 100 - 420 - - - - - 640 - 16777215 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 100 - 100 - - - - - 16777215 - 16777215 - - - - - - - :/images/Resources/missing-image.png - - - false - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - 100 - 100 - - - - - - - - - 16777215 - 140 - - - - - 0 - - - - - Image: - - - true - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 16777215 - 16777215 - - - - Clear - - - - - - - - 16777215 - 16777215 - - - - Library... - - - - - - - - 16777215 - 16777215 - - - - Load... - - - - - - - - - - - - - - - - 1280 - 1280 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 16777215 - 20 - - - - Article: 0 - - - - - - - 0 - - - 0 - - - 3 - - - 0 - - - 3 - - - - - Default Style - - - true - - - default - - - articleStyleButtonGroup - - - - - - - Pinned Style - - - pinned - - - articleStyleButtonGroup - - - - - - - - - Title: - - - - - - - true - - - - - - - - - - 0 - - - - - Description: - - - - - - - - - - 0 - - - - - 0 - - - - - Delete - - - - - - - Cancel - - - - - - - Save - - - - - - - - - 0 - - - - - - 16777215 - 16777215 - - - - Move Up - - - - - - - - 16777215 - 16777215 - - - - Move Down - - - - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - - - - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp deleted file mode 100644 index 586978a562..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDetailsContainer.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetails.h" -#include "Qt/ui_ArticleDetailsContainer.h" - -namespace News -{ - - ArticleDetailsContainer::ArticleDetailsContainer( - QWidget* parent, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleDetailsContainerWidget) - , m_manifest(manifest) - , m_articleDetails(nullptr) - { - m_ui->setupUi(this); - } - - ArticleDetailsContainer::~ArticleDetailsContainer() {} - - //! When article is selected, old articleDetails control is removed, new one is created - void ArticleDetailsContainer::SelectArticle(const QString& id) - { - closeArticleSlot(); - - if (!id.isEmpty()) - { - auto article = m_manifest.FindById(id); - if (article) - { - m_articleDetails = new ArticleDetails( - m_ui->scrollAreaWidgetContents, - *article, - m_manifest); - m_ui->scrollAreaWidgetContents->layout()->addWidget(m_articleDetails); - connect(m_articleDetails, &ArticleDetails::updateArticleSignal, - this, &ArticleDetailsContainer::updateArticleSlot); - connect(m_articleDetails, &ArticleDetails::deleteArticleSignal, - this, &ArticleDetailsContainer::deleteArticleSlot); - connect(m_articleDetails, &ArticleDetails::closeArticleSignal, - this, &ArticleDetailsContainer::closeArticleSlot); - connect(m_articleDetails, SIGNAL(logSignal(QString, LogType)), - this, SIGNAL(logSignal(QString, LogType))); - connect(m_articleDetails, SIGNAL(orderChangedSignal(QString, bool)), - this, SIGNAL(orderChangedSignal(QString, bool))); - m_selectedId = id; - } - } - } - - void ArticleDetailsContainer::Reset() - { - SelectArticle(m_selectedId); - } - - void ArticleDetailsContainer::updateArticleSlot() - { - emit updateArticleSignal(m_articleDetails->GetId()); - } - - void ArticleDetailsContainer::deleteArticleSlot() - { - emit deleteArticleSignal(m_articleDetails->GetId()); - closeArticleSlot(); - } - - void ArticleDetailsContainer::closeArticleSlot() - { - if (m_articleDetails) - { - emit closeArticleSignal(m_selectedId); - delete m_articleDetails; - m_articleDetails = nullptr; - m_selectedId = ""; - } - } - -#include "Qt/moc_ArticleDetailsContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h deleted file mode 100644 index 1df42198c3..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class ArticleDetailsContainerWidget; -} - -namespace News -{ - class ArticleDetails; - class BuilderResourceManifest; - class SelectImage; - class ResourceManifest; - class Resource; - - //! Control that manages articleDetails control - class ArticleDetailsContainer - : public QWidget - { - Q_OBJECT - - public: - ArticleDetailsContainer(QWidget* parent, BuilderResourceManifest& manifest); - ~ArticleDetailsContainer(); - - void SelectArticle(const QString& id); - void Reset(); - -Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void updateArticleSignal(QString id); - void deleteArticleSignal(QString id); - void closeArticleSignal(QString id); - void orderChangedSignal(QString id, bool direction); - - private: - QScopedPointer m_ui; - BuilderResourceManifest& m_manifest; - ArticleDetails* m_articleDetails = nullptr; - QString m_selectedId; - - private Q_SLOTS: - void updateArticleSlot(); - void deleteArticleSlot(); - void closeArticleSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui deleted file mode 100644 index 7652fa114d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui +++ /dev/null @@ -1,100 +0,0 @@ - - - ArticleDetailsContainerWidget - - - - 0 - 0 - 250 - 386 - - - - - 0 - 0 - - - - - 250 - 0 - - - - - 640 - 16777215 - - - - ArticleDetailsContainer - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 248 - 384 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui b/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui deleted file mode 100644 index f58243ed8d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui +++ /dev/null @@ -1,102 +0,0 @@ - - - Dialog - - - - 0 - 0 - 176 - 137 - - - - - 0 - 0 - - - - Dialog - - - - - - - - - - AWS Key Id: - - - - - - - - - - - - - - AWS Secret Key: - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp deleted file mode 100644 index bf77a89895..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "BuilderArticleViewContainer.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetails.h" -#include -#include -#include -#include "Qt/ui_BuilderArticleViewContainer.h" - -#include - -#include "QCustomMessageBox.h" - -namespace News -{ - - BuilderArticleViewContainer::BuilderArticleViewContainer( - QWidget* parent, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::BuilderArticleViewContainerWidget) - , m_container(new ArticleViewContainer(this, manifest)) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - m_ui->ArticleViewContainerRoot->layout()->addWidget(m_container); - connect(m_container, SIGNAL(articleSelectedSignal(QString)), - this, SLOT(articleSelectedSlot(QString))); - } - - BuilderArticleViewContainer::~BuilderArticleViewContainer(){} - - void BuilderArticleViewContainer::AddArticle() - { - auto pArticleResource = static_cast(m_manifest).AddArticle(); - if (pArticleResource) - { - m_container->AddArticleView(ArticleDescriptor(*pArticleResource)); - SelectArticle(pArticleResource->GetId()); - } - } - - void BuilderArticleViewContainer::SelectArticle(QString id) - { - if (m_selectedArticleId.compare(id) == 0) - { - return; - } - - UnselectArticle(); - m_selectedArticleId = id; - auto article = m_container->FindById(id); - if (article) - { - m_container->ScrollToView(article); - emit articleSelectedSignal(id); - - // Add class and refresh style - AzQtComponents::Style::addClass(article, m_selectedArticleClass); - article->style()->unpolish(qApp); - article->style()->polish(qApp); - } - } - - void BuilderArticleViewContainer::Sync() - { - emit logSignal("Starting sync"); - - m_manifest.Sync(); - } - - void BuilderArticleViewContainer::UpdateArticle(QString& id) const - { - auto view = m_container->FindById(id); - if (view) - { - view->Update(); - m_container->ForceRefreshArticleView(view); - } - } - - void BuilderArticleViewContainer::DeleteArticle(QString& id) const - { - auto view = m_container->FindById(id); - if (view) - { - m_container->DeleteArticleView(view); - } - } - - //possibly support multiple selection in future? - void BuilderArticleViewContainer::CloseArticle(QString& id) - { - if (m_selectedArticleId == id) - { - UnselectArticle(); - } - } - - void BuilderArticleViewContainer::UpdateArticleOrder(QString& id, bool direction) const - { - auto view = m_container->FindById(id); - if (view) - { - m_container->UpdateArticleOrder(view, direction); - } - } - - void BuilderArticleViewContainer::PopulateArticles() - { - m_container->PopulateArticles(); - - if (!m_selectedArticleId.isEmpty()) - { - SelectArticle(m_selectedArticleId); - } - } - - void BuilderArticleViewContainer::AddErrorMessage() const - { - m_container->AddErrorMessage(); - } - - void BuilderArticleViewContainer::UnselectArticle() - { - if (m_selectedArticleId.isEmpty()) - { - return; - } - auto article = m_container->FindById(m_selectedArticleId); - - // Remove class and refresh style - if (article) - { - AzQtComponents::Style::removeClass(article, m_selectedArticleClass); - article->style()->unpolish(qApp); - article->style()->polish(qApp); - } - - m_selectedArticleId = ""; - } - - void BuilderArticleViewContainer::articleSelectedSlot(QString id) - { - SelectArticle(id); - } - -#include "Qt/moc_BuilderArticleViewContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h deleted file mode 100644 index 94712ca768..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class BuilderArticleViewContainerWidget; -} - -namespace News -{ - class ArticleViewContainer; - class BuilderResourceManifest; - - //! BuilderArticleViewContainer is a Builder container for ArticleViewContainer. - /*! - It is a wrapper with additional builder functionality for displaying articles - */ - class BuilderArticleViewContainer - : public QWidget - { - Q_OBJECT - public: - BuilderArticleViewContainer(QWidget* parent, BuilderResourceManifest& manifest); - ~BuilderArticleViewContainer(); - - void UpdateArticle(QString& id) const; - void DeleteArticle(QString& id) const; - void CloseArticle(QString& id); - void UpdateArticleOrder(QString& id, bool direction) const; - void PopulateArticles(); - void AddErrorMessage() const; - void AddArticle(); - -Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void articleSelectedSignal(QString id); - - private: - QScopedPointer m_ui; - ArticleViewContainer* m_container; - QString m_selectedArticleId; - QString m_selectedArticleClass = "SelectedArticle"; - BuilderResourceManifest& m_manifest; - - void Sync(); - void SelectArticle(QString id); - void UnselectArticle(); - - - private Q_SLOTS: - void articleSelectedSlot(QString id); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui deleted file mode 100644 index dafac9b9ff..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui +++ /dev/null @@ -1,57 +0,0 @@ - - - BuilderArticleViewContainerWidget - - - - 0 - 0 - 250 - 500 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp deleted file mode 100644 index 5e698eea97..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointEntryView.h" -#include "Qt/ui_EndpointEntryView.h" -#include -#include - -namespace News -{ - - const char* EndpointEntryView::SELECTED_CSS = - "background-color: rgb(60, 100, 60);\ncolor: white;"; - const char* EndpointEntryView::UNSELECTED_CSS = - "background-color: rgb(60, 60, 60);\ncolor: white;"; - - EndpointEntryView::EndpointEntryView(QWidget* parent, Endpoint* pEndpoint) - : QWidget(parent) - , m_ui(new Ui::EndpointEntryViewWidget) - , m_pEndpoint(pEndpoint) - { - m_ui->setupUi(this); - - m_ui->labelName->setText(pEndpoint->GetName()); - - connect(m_ui->labelName, &AzQtComponents::ExtendedLabel::clicked, this, &EndpointEntryView::selectSlot); - connect(m_ui->buttonDelete, &QToolButton::clicked, this, &EndpointEntryView::deleteSlot); - } - - EndpointEntryView::~EndpointEntryView() {} - - void EndpointEntryView::SetSelected(bool selected) - { - setStyleSheet(selected ? SELECTED_CSS : UNSELECTED_CSS); - } - - Endpoint* EndpointEntryView::GetEndpoint() const - { - return m_pEndpoint; - } - - void EndpointEntryView::selectSlot() - { - emit selectSignal(this); - } - - void EndpointEntryView::deleteSlot() - { - emit deleteSignal(this); - } - -#include "Qt/moc_EndpointEntryView.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h deleted file mode 100644 index c8b014c167..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class EndpointEntryViewWidget; -} - -namespace News -{ - class Endpoint; - - //! Qt widget representing a single endpoint entry - class EndpointEntryView - : public QWidget - { - Q_OBJECT - public: - EndpointEntryView(QWidget* parent, Endpoint* pEndpoint); - ~EndpointEntryView(); - - void SetSelected(bool selected); - - Endpoint* GetEndpoint() const; - - Q_SIGNALS: - void selectSignal(EndpointEntryView* pEndpointView); - void deleteSignal(EndpointEntryView* pEndpointView); - - private: - static const char* SELECTED_CSS; - static const char* UNSELECTED_CSS; - - QScopedPointer m_ui; - Endpoint* m_pEndpoint = nullptr; - - private Q_SLOTS: - void selectSlot(); - void deleteSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui deleted file mode 100644 index 309fcd5662..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui +++ /dev/null @@ -1,87 +0,0 @@ - - - EndpointEntryViewWidget - - - - 0 - 0 - 356 - 23 - - - - - 0 - 23 - - - - - 16777215 - 23 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - - 25 - 0 - - - - - 25 - 16777215 - - - - background-color: red; - - - X - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp deleted file mode 100644 index e28245b895..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointManagerView.h" -#include "EndpointManager.h" -#include "EndpointEntryView.h" -#include "Qt/ui_EndpointManagerView.h" -#include "Qt/QCustomMessageBox.h" -#include "ResourceManagement/BuilderResourceManifest.h" - -#include - -namespace News -{ - - EndpointManagerView::EndpointManagerView(QWidget* parent, - BuilderResourceManifest& manifest) - : QDialog(parent) - , m_ui(new Ui::EndpointManagerViewWidget) - , m_pManager(manifest.GetEndpointManager()) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - for (auto endpoint : *m_pManager) - { - auto endpointView = AddEndpointEntry(endpoint); - if (m_pManager->GetSelectedEndpoint() == endpoint) - { - selectEndpointSlot(endpointView); - } - } - - connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - connect(m_ui->buttonAdd, &QPushButton::clicked, this, &EndpointManagerView::addEndpointSlot); - } - - EndpointManagerView::~EndpointManagerView() {} - - EndpointEntryView* EndpointManagerView::AddEndpointEntry(Endpoint* pEndpoint) - { - auto endpointView = new EndpointEntryView(m_ui->endpointListContents, pEndpoint); - auto layout = static_cast(m_ui->endpointListContents->layout()); - layout->insertWidget(layout->count() - 2, endpointView); - m_endpoints.append(endpointView); - connect(endpointView, SIGNAL(selectSignal(EndpointEntryView*)), - this, SLOT(selectEndpointSlot(EndpointEntryView*))); - connect(endpointView, SIGNAL(deleteSignal(EndpointEntryView*)), - this, SLOT(deleteEndpointSlot(EndpointEntryView*))); - // this lets us modify newly-added widget in the same function - qApp->processEvents(); - return endpointView; - } - - void EndpointManagerView::Update() const - { - if (m_pSelectedEndpoint) - { - auto pEndpoint = m_pSelectedEndpoint->GetEndpoint(); - pEndpoint->SetName(m_ui->nameText->text()); - pEndpoint->SetAwsProfile(m_ui->awsProfileText->text()); - pEndpoint->SetUrl(m_ui->urlText->text()); - pEndpoint->SetBucket(m_ui->bucketText->text()); - m_pManager->SelectEndpoint(m_pSelectedEndpoint->GetEndpoint()); - } - m_pManager->Save(); - } - - void EndpointManagerView::accept() - { - enum SyncResponse - { - Merge, ReplaceLocal, ReplaceRemote, Cancel - }; - enum YesNoResponse - { - Yes, No - }; - - QCustomMessageBox msgBox( - QCustomMessageBox::Question, - tr("Pull data from Endpoint"), - tr("You are changing an endpoint. " - "What would you like to do with the data on the current endpoint?\n\n" - "Merge - merge resources from the endpoint\n" - "Replace Local - overwrite local resources with endpoint resources\n" - "Replace Endpoint - overwrite endpoint resources with local resources\n" - "Cancel - undo endpoint selection" - ), - this); - msgBox.AddButton(tr("Merge"), Merge); - msgBox.AddButton(tr("Replace Local"), ReplaceLocal); - msgBox.AddButton(tr("Replace Endpoint"), ReplaceRemote); - msgBox.AddButton(tr("Cancel"), Cancel); - - switch (msgBox.exec()) - { - case Merge: - { - m_manifest.SetSyncType(SyncType::Merge); - m_manifest.PersistLocalResources(); - } - break; - case ReplaceLocal: - { - if (m_manifest.HasChanges()) - { - QCustomMessageBox msgBoxWarning( - QCustomMessageBox::Critical, - tr("Unsaved changes"), - tr("Local resources were modified but not published." - "Changing endpoints will cause unpublished work to be lost.\n\n" - "Would you like to proceed?"), - this); - msgBoxWarning.AddButton(tr("Yes"), Yes); - msgBoxWarning.AddButton(tr("No"), No); - if (msgBoxWarning.exec() == No) - { - return; - } - } - m_manifest.SetSyncType(SyncType::Merge); - m_manifest.Reset(); - } - break; - case ReplaceRemote: - { - QCustomMessageBox msgBoxWarning2( - QCustomMessageBox::Critical, - tr("Warning"), - tr("This operation will IRREVERSABLY replace ALL resources on ") + - m_pSelectedEndpoint->GetEndpoint()->GetName() + - tr(" endpoint with local data.\n\n" - "Are you sure you'd like to proceed?"), - this); - msgBoxWarning2.AddButton(tr("Yes"), Yes); - msgBoxWarning2.AddButton(tr("No"), No); - if (msgBoxWarning2.exec() == No) - { - return; - } - m_manifest.SetSyncType(SyncType::Overwrite); - m_manifest.PersistLocalResources(); - } - break; - case Cancel: - return; - } - - Update(); - - QDialog::accept(); - } - - void EndpointManagerView::addEndpointSlot() - { - auto pEndpoint = new Endpoint( - QObject::tr("New endpoint"), - QObject::tr("Enter AWS profile name"), - QObject::tr("Enter root URL"), - QObject::tr("Enter s3 bucket name")); - m_pManager->AddEndpoint(pEndpoint); - auto endpointView = AddEndpointEntry(pEndpoint); - selectEndpointSlot(endpointView); - } - - void EndpointManagerView::selectEndpointSlot(EndpointEntryView* pEndpointView) - { - m_pSelectedEndpoint = pEndpointView; - - for (auto view : m_endpoints) - { - view->SetSelected(view == pEndpointView); - } - - if (pEndpointView) - { - auto pEndpoint = pEndpointView->GetEndpoint(); - m_ui->nameText->setText(pEndpoint->GetName()); - m_ui->awsProfileText->setText(pEndpoint->GetAwsProfile()); - m_ui->urlText->setText(pEndpoint->GetUrl()); - m_ui->bucketText->setText(pEndpoint->GetBucket()); - } - else - { - m_ui->nameText->setText(""); - m_ui->awsProfileText->setText(""); - m_ui->urlText->setText(""); - m_ui->bucketText->setText(""); - } - } - - void EndpointManagerView::deleteEndpointSlot(EndpointEntryView* pEndpointView) - { - m_pManager->RemoveEndpoint(pEndpointView->GetEndpoint()); - m_endpoints.removeAll(pEndpointView); - - if (pEndpointView == m_pSelectedEndpoint) - { - if (m_endpoints.count() > 0) - { - selectEndpointSlot(m_endpoints[0]); - } - else - { - selectEndpointSlot(nullptr); - } - } - - delete pEndpointView; - } - - -#include "Qt/moc_EndpointManagerView.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h deleted file mode 100644 index c6362a06af..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class EndpointManagerViewWidget; -} - -namespace News -{ - class BuilderResourceManifest; - class Endpoint; - class EndpointEntryView; - class EndpointManager; - - //! Qt dialog for managing endpoints - class EndpointManagerView - : public QDialog - { - Q_OBJECT - public: - EndpointManagerView(QWidget* parent, - BuilderResourceManifest& manifest); - ~EndpointManagerView(); - - private: - QScopedPointer m_ui; - EndpointManager* m_pManager = nullptr; - EndpointEntryView* m_pSelectedEndpoint = nullptr; - QList m_endpoints; - BuilderResourceManifest& m_manifest; - - EndpointEntryView* AddEndpointEntry(Endpoint* pEndpoint); - void Update() const; - - private Q_SLOTS: - void accept() override; - void addEndpointSlot(); - void selectEndpointSlot(EndpointEntryView* pEndpoint); - void deleteEndpointSlot(EndpointEntryView* pEndpoint); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui deleted file mode 100644 index 5295e30616..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui +++ /dev/null @@ -1,224 +0,0 @@ - - - EndpointManagerViewWidget - - - - 0 - 0 - 400 - 350 - - - - - 400 - 350 - - - - - 400 - 350 - - - - Change Endpoint - - - Qt::LeftToRight - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 363 - 189 - - - - - - - + - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Name: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - AWS Profile Name: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - URL: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - S3 Bucket - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp b/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp deleted file mode 100644 index 1566b8309d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ImageItem.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include "Qt/ui_ImageItem.h" - -namespace News -{ - - const char* ImageItem::SELECTED_CSS = - "border: 4px solid; border-color: white; background-color: rgb(45, 45, 45);"; - const char* ImageItem::UN_SELECTED_CSS = - "background-color: rgb(45, 45, 45);"; - - ImageItem::ImageItem(Resource& resource) - : QWidget() - , m_ui(new Ui::ImageItemWidget) - , m_resource(resource) - { - m_ui->setupUi(this); - - QPixmap pixmap; - pixmap.loadFromData(m_resource.GetData()); - m_ui->ImageLabel->setPixmap(pixmap); - - connect(m_ui->ImageLabel, &AzQtComponents::ExtendedLabel::clicked, this, &ImageItem::imageClickedSlot); - } - - void ImageItem::imageClickedSlot() - { - emit selectSignal(this); - } - - ImageItem::~ImageItem() {} - - void ImageItem::SetSelect(bool selected) const - { - m_ui->ImageLabel->setStyleSheet(selected ? SELECTED_CSS : UN_SELECTED_CSS); - } - - Resource& ImageItem::GetResource() const - { - return m_resource; - } - -#include "Qt/moc_ImageItem.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.h b/Code/Tools/News/NewsBuilder/Qt/ImageItem.h deleted file mode 100644 index ba883bc736..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ImageItemWidget; -} - -namespace News { - class Resource; - - //! A clickable image in selectImage control - class ImageItem - : public QWidget - { - Q_OBJECT - public: - explicit ImageItem(Resource& resource); - ~ImageItem(); - - void SetSelect(bool selected) const; - Resource& GetResource() const; - - Q_SIGNALS: - void selectSignal(ImageItem* imageItem); - - private: - QScopedPointer m_ui; - const static char* SELECTED_CSS; - const static char* UN_SELECTED_CSS; - - Resource& m_resource; - private Q_SLOTS: - void imageClickedSlot(); - }; -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui b/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui deleted file mode 100644 index 9aef880c10..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui +++ /dev/null @@ -1,65 +0,0 @@ - - - ImageItemWidget - - - - 0 - 0 - 200 - 200 - - - - - 200 - 200 - - - - - 200 - 200 - - - - Form - - - - 20 - - - 20 - - - 20 - - - 20 - - - - - - - - - 160 - 90 - - - - - - - - - AzQtComponents::ExtendedLabel1 - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp deleted file mode 100644 index 5efda641db..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "LogContainer.h" - -#include "Qt/ui_LogContainer.h" - -namespace News -{ - - LogContainer::LogContainer(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::LogContainerWidget) - { - m_ui->setupUi(this); - } - - LogContainer::~LogContainer() {} - - void LogContainer::AddLog(QString text, LogType logType) const { - QString color; - switch (logType) - { - case LogOk: - color = "green"; - break; - case LogInfo: - color = "white"; - break; - case LogError: - color = "red"; - break; - case LogWarning: - color = "yellow"; - break; - default: - color = "white"; - break; - } - auto fullText = QString("%2
").arg(color).arg(text); - m_ui->logText->setTextFormat(Qt::RichText); - m_ui->logText->setText(QString("%2%1").arg(m_ui->logText->text()).arg(fullText)); - } - -#include "Qt/moc_LogContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.h b/Code/Tools/News/NewsBuilder/Qt/LogContainer.h deleted file mode 100644 index 8f46f3b406..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class LogContainerWidget; -} - -namespace News -{ - //! A control for displaying log - class LogContainer - : public QWidget - { - Q_OBJECT - - public: - explicit LogContainer(QWidget* parent); - ~LogContainer(); - - void AddLog(QString text, LogType logType) const; - - private: - QScopedPointer m_ui; - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui b/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui deleted file mode 100644 index 3757f52480..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui +++ /dev/null @@ -1,131 +0,0 @@ - - - LogContainerWidget - - - - 0 - 0 - 547 - 125 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - LogContainer - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 545 - 123 - - - - - 0 - 0 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - background-color: rgb(45, 45, 45); - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - false - - - Qt::TextBrowserInteraction - - - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp b/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp deleted file mode 100644 index 5cbb510dd6..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include "NewsBuilder.h" -#include "Qt/ArticleDetails.h" -#include "Qt/BuilderArticleViewContainer.h" -#include "NewsShared/Qt/ArticleViewContainer.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetailsContainer.h" -#include "LogContainer.h" -#include "EndpointManagerView.h" -#include "EndpointManager.h" -#include "Qt/QCustomMessageBox.h" - -#include -#include - -AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include -#include - -#include "Qt/ui_Newsbuilder.h" - -namespace News -{ - NewsBuilder::NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath) - : QMainWindow(parent) - , m_ui(new Ui::NewsBuilderClass()) - , m_manifest(new BuilderResourceManifest( - std::bind(&NewsBuilder::SyncSuccess, this), - std::bind(&NewsBuilder::SyncFail, this, std::placeholders::_1), - std::bind(&NewsBuilder::SyncUpdate, this, std::placeholders::_1, std::placeholders::_2))) - , m_articleDetailsContainer(new ArticleDetailsContainer(this, *m_manifest)) - , m_articleViewContainer(new BuilderArticleViewContainer(this, *m_manifest)) - , m_logContainer(new LogContainer(this)) - { - - AzQtComponents::StyleManager* m_styleSheet = new AzQtComponents::StyleManager(this); - m_styleSheet->initialize(qApp, engineRootPath); - - m_ui->setupUi(this); - - QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast(engineRootPath.Native().size())); - const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/News/NewsBuilder/Resources"); - const auto qrcPath = QStringLiteral(":/NewsBuilder"); - AzQtComponents::StyleManager::addSearchPaths("newsbuilder", pathOnDisk, qrcPath, engineRootPath); - - AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("newsbuilder:NewsBuilder.qss")); - - UpdateEndpointLabel(); - - m_ui->articleViewContainerRoot->layout()->addWidget(m_articleViewContainer); - m_ui->articleDetailsContainerRoot->layout()->addWidget(m_articleDetailsContainer); - m_ui->dockWidgetContents->layout()->addWidget(m_logContainer); - - connect(m_articleViewContainer, SIGNAL(articleSelectedSignal(QString)), - this, SLOT(selectArticleSlot(QString))); - connect(m_articleViewContainer, SIGNAL(logSignal(QString, LogType)), - this, SLOT(addLogSlot(QString, LogType))); - - connect(m_articleDetailsContainer, &ArticleDetailsContainer::updateArticleSignal, - this, &NewsBuilder::updateArticleSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::deleteArticleSignal, - this, &NewsBuilder::deleteArticleSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::orderChangedSignal, - this, &NewsBuilder::orderChangedSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::closeArticleSignal, - this, &NewsBuilder::closeArticleSlot); - connect(m_articleDetailsContainer, SIGNAL(logSignal(QString, LogType)), - this, SLOT(addLogSlot(QString, LogType))); - - m_manifest->SetSyncType(SyncType::Merge); - m_manifest->Sync(); - - // Sync Console pane with View menu - connect(m_ui->actionConsole, &QAction::triggered, this, &NewsBuilder::OnViewLogWindow); - connect(m_ui->dockWidget, &QDockWidget::visibilityChanged, this, &NewsBuilder::OnViewVisibilityChanged); - } - - NewsBuilder::~NewsBuilder() {} - - void NewsBuilder::selectArticleSlot(const QString& id) const - { - m_articleDetailsContainer->SelectArticle(id); - } - - void NewsBuilder::addLogSlot(QString text, LogType logType) const - { - AddLog(text, logType); - } - - void NewsBuilder::addArticleToBottomSlot() const - { - m_articleViewContainer->AddArticle(); - } - - void NewsBuilder::updateArticleSlot(QString id) const - { - m_articleViewContainer->UpdateArticle(id); - } - - void NewsBuilder::deleteArticleSlot(QString id) const - { - m_articleViewContainer->DeleteArticle(id); - } - - void NewsBuilder::closeArticleSlot(QString id) const - { - m_articleViewContainer->CloseArticle(id); - } - - void NewsBuilder::orderChangedSlot(QString id, bool direction) const - { - m_articleViewContainer->UpdateArticleOrder(id, direction); - } - - void NewsBuilder::openSlot() - { - EndpointManagerView endpointManagerView( - m_ui->centralWidget, - *m_manifest); - if (endpointManagerView.exec() == QDialog::Accepted) - { - m_manifest->Sync(); - } - UpdateEndpointLabel(); - } - - void NewsBuilder::publishSlot() - { - if (!m_manifest->HasChanges()) - { - QCustomMessageBox msgBox( - QCustomMessageBox::Information, - tr("Nothing to publish"), - tr("No local changes were made, nothing to publish."), - this); - msgBox.AddButton(tr("Good"), 0); - msgBox.exec(); - return; - } - - enum Response - { - Yes, No - }; - - QCustomMessageBox msgBox( - QCustomMessageBox::Critical, - tr("Publish resources"), - tr("You are about to overwrite the current Open 3D Engine Welcome Message. Are you sure you want to publish?"), - this); - msgBox.AddButton("Yes", Yes); - msgBox.AddButton("No", No); - if (msgBox.exec() == Yes) - { - m_manifest->SetSyncType(SyncType::Verify); - m_manifest->Sync(); - } - } - - void NewsBuilder::OnViewVisibilityChanged([[maybe_unused]] bool visibility) - { - UpdateViewMenu(); - } - - void NewsBuilder::UpdateViewMenu() - { - if (m_ui->actionConsole->isChecked() != m_ui->dockWidget->isVisible()) - { - QSignalBlocker signalBlocker(m_ui->actionConsole); - m_ui->actionConsole->setChecked(m_ui->dockWidget->isVisible()); - } - } - - void NewsBuilder::OnViewLogWindow() - { - if (m_ui->dockWidget) - { - m_ui->dockWidget->toggleViewAction()->trigger(); - } - } - - void NewsBuilder::UpdateEndpointLabel() - { - auto pEndpoint = m_manifest->GetEndpointManager()->GetSelectedEndpoint(); - if (pEndpoint) - { - this->setWindowTitle("News Builder (" + pEndpoint->GetName() + ")"); - } - else - { - this->setWindowTitle("News Builder (No endpoint selected)"); - } - } - - void NewsBuilder::AddLog(QString text, LogType logType) const - { - m_logContainer->AddLog(text, logType); - } - - void NewsBuilder::SyncUpdate(const QString& message, LogType logType) const - { - AddLog(message, logType); - } - - void NewsBuilder::SyncFail(ErrorCode error) - { - const char* errorMessage = GetErrorMessage(error); - AddLog(tr("Sync failed: %1").arg(errorMessage), LogError); - QCustomMessageBox msgBoxSyncFail( - QCustomMessageBox::Critical, - tr("Sync failed"), - errorMessage, - this); - msgBoxSyncFail.AddButton("Ok", 0); - msgBoxSyncFail.exec(); - - m_articleViewContainer->PopulateArticles(); - m_articleDetailsContainer->Reset(); - } - - void NewsBuilder::SyncSuccess() const - { - AddLog("Sync completed", LogOk); - m_articleViewContainer->PopulateArticles(); - m_articleDetailsContainer->Reset(); - } -#include "Qt/moc_NewsBuilder.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h b/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h deleted file mode 100644 index 61e25bda1b..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include - -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" - -#include -#endif - -class QSignalMapper; -class QPushButton; - -namespace Ui -{ - class NewsBuilderClass; -} - -namespace News -{ - class BuilderArticleViewContainer; - class LogContainer; - class BuilderResourceManifest; - class ArticleDetailsContainer; - - //! A central control of News Builder. - class NewsBuilder - : public QMainWindow - { - Q_OBJECT - - public: - explicit NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath); - ~NewsBuilder(); - - private: - QScopedPointer m_ui; - BuilderResourceManifest* m_manifest = nullptr; - ArticleDetailsContainer* m_articleDetailsContainer = nullptr; - BuilderArticleViewContainer* m_articleViewContainer = nullptr; - LogContainer* m_logContainer = nullptr; - - void UpdateEndpointLabel(); - void AddLog(QString text, LogType logType = LogInfo) const; - - void SyncUpdate(const QString& message, LogType logType) const; - void SyncFail(ErrorCode error); - void SyncSuccess() const; - - void OnViewVisibilityChanged(bool visibility); - void UpdateViewMenu(); - void OnViewLogWindow(); - - private Q_SLOTS: - void selectArticleSlot(const QString& id) const; - void addLogSlot(QString text, LogType logType) const; - void addArticleToBottomSlot() const; - void updateArticleSlot(QString id) const; - void deleteArticleSlot(QString id) const; - void closeArticleSlot(QString id) const; - void orderChangedSlot(QString id, bool direction) const; - void openSlot(); - void publishSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc b/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc deleted file mode 100644 index 768281fb12..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - ../Resources/missing-image.png - - diff --git a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui b/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui deleted file mode 100644 index 55e7fe5b68..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui +++ /dev/null @@ -1,326 +0,0 @@ - - - NewsBuilderClass - - - - 0 - 0 - 800 - 540 - - - - - 0 - 480 - - - - - 1024 - 16777215 - - - - News Builder - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 800 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 480 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 0 - - - 5 - - - 5 - - - 5 - - - 5 - - - - - - - - - - - - - 0 - 0 - 800 - 21 - - - - - File - - - - - - - Article - - - - - - View - - - - - - - - - - - 0 - 0 - - - - - 63 - 66 - - - - QDockWidget::DockWidgetClosable - - - Qt::BottomDockWidgetArea - - - Console - - - 8 - - - - - 5 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Change Endpoint - - - false - - - - - Publish Resources - - - false - - - - - Add to Bottom - - - - - Delete Selected - - - - - true - - - Console - - - - - - - AzQtComponents::StyledDockWidget - QDockWidget -
AzQtComponents/Components/StyledDockWidget.h
- 1 -
-
- - - - - - actionOpen - triggered() - NewsBuilderClass - openSlot() - - - -1 - -1 - - - 399 - 269 - - - - - actionPublish - triggered() - NewsBuilderClass - publishSlot() - - - -1 - -1 - - - 399 - 269 - - - - - actionAdd_New - triggered() - NewsBuilderClass - addArticleToBottomSlot() - - - -1 - -1 - - - 399 - 269 - - - - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp deleted file mode 100644 index 1b92f91e42..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QCustomMessageBox.h" -#include "Qt/ui_QCustomMessageBox.h" - -#include -#include -#include - -namespace News -{ - - QCustomMessageBox::QCustomMessageBox( - Icon icon, - const QString& title, - const QString& text, - QWidget* parent) - : QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint) - , m_ui(new Ui::CustomMessageBoxDialog) - { - m_ui->setupUi(this); - - m_signalMapper = new QSignalMapper(this); - - this->setWindowTitle(title); - m_ui->labelText->setText(text); - - QStyle* style = QApplication::style(); - QIcon tmpIcon; - switch (icon) - { - case Information: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation); - break; - case Warning: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning); - break; - case Critical: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical); - break; - case Question: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion); - default: - break; - } - if (!tmpIcon.isNull()) - { - QLabel* iconLabel = new QLabel(this); - iconLabel->setPixmap(tmpIcon.pixmap(64, 64)); - m_ui->bodyLayout->insertWidget(0, iconLabel); - } - - connect(m_signalMapper, SIGNAL(mapped(int)), - this, SLOT(clickedSlot(int))); - } - - QCustomMessageBox::~QCustomMessageBox() - { - delete m_signalMapper; - } - - void QCustomMessageBox::AddButton(const QString& name, int result) - { - auto button = new QPushButton(name, this); - connect(button, SIGNAL(clicked()), m_signalMapper, SLOT(map())); - m_signalMapper->setMapping(button, result); - m_ui->buttonLayout->layout()->addWidget(button); - } - - void QCustomMessageBox::clickedSlot(int result) - { - done(result); - } - -#include "Qt/moc_QCustomMessageBox.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h deleted file mode 100644 index 6cd6771514..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -class QSignalMapper; - -namespace Ui -{ - class CustomMessageBoxDialog; -} - -namespace News -{ - class ArticleDetails; - class BuilderResourceManifest; - class SelectImage; - class ResourceManifest; - class Resource; - - //! Allows to add custom buttons which is not well-supported by default QMessageBox - class QCustomMessageBox - : public QDialog - { - Q_OBJECT - - public: - enum Icon { - NoIcon = 0, - Information = 1, - Warning = 2, - Critical = 3, - Question = 4 - }; - - QCustomMessageBox( - Icon, - const QString& title, - const QString& text, - QWidget* parent); - ~QCustomMessageBox(); - - void AddButton(const QString& name, int result); - - private: - QScopedPointer m_ui; - QSignalMapper* m_signalMapper = nullptr; - - private Q_SLOTS: - void clickedSlot(int result); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui deleted file mode 100644 index c1fb5f40bf..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui +++ /dev/null @@ -1,84 +0,0 @@ - - - CustomMessageBoxDialog - - - - 0 - 0 - 102 - 43 - - - - - 0 - 0 - - - - Message Title - - - - - - - - - - - Message text - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - 0 - - - - - Qt::Horizontal - - - - 40 - 0 - - - - - - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 0 - - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp b/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp deleted file mode 100644 index 7a9e427f4b..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "SelectImage.h" -#include "ImageItem.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "ResourceManagement/BuilderResourceManifest.h" - -#include "Qt/ui_SelectImage.h" - -namespace News -{ - - const int SelectImage::MAX_COLS = 2; - - SelectImage::SelectImage(const ResourceManifest& manifest) - : QDialog() - , m_ui(new Ui::SelectImageDialog) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - auto layout = static_cast(m_ui->scrollAreaContents->layout()); - layout->setAlignment(Qt::AlignTop | Qt::AlignLeft); - int row = 0; - int col = 0; - //! read all image resources and populate the container - for (auto pResource : m_manifest) - { - if (pResource->GetType().compare("image") == 0) - { - auto imageItem = new ImageItem(*pResource); - connect(imageItem, &ImageItem::selectSignal, this, &SelectImage::ImageSelected); - layout->addWidget(imageItem, row, col, Qt::AlignLeft); - m_images.append(imageItem); - col++; - if (col >= MAX_COLS) - { - col = 0; - row++; - } - } - } - - connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - } - - SelectImage::~SelectImage() {} - - Resource* SelectImage::GetSelected() const - { - return m_pSelected; - } - - void SelectImage::ImageSelected(ImageItem* imageItem) - { - for (auto image : m_images) - { - image->SetSelect(image == imageItem); - } - if (imageItem) - { - m_pSelected = &imageItem->GetResource(); - } - } - -#include "Qt/moc_SelectImage.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.h b/Code/Tools/News/NewsBuilder/Qt/SelectImage.h deleted file mode 100644 index 5fc80cfe5a..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class SelectImageDialog; -} - -namespace News { - class ImageItem; - class Resource; - class ResourceManifest; - - //! Allows to select existing images for multiple messages without re-uploading same one - class SelectImage - : public QDialog - { - Q_OBJECT - public: - explicit SelectImage(const ResourceManifest& manifest); - ~SelectImage(); - - void Select(); - void Close(); - Resource* GetSelected() const; - - private: - const static int MAX_COLS; - QScopedPointer m_ui; - const ResourceManifest& m_manifest; - QList m_images; - Resource* m_pSelected = nullptr; - - void ImageSelected(ImageItem* imageItem); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui b/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui deleted file mode 100644 index 55b27bfb7f..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui +++ /dev/null @@ -1,106 +0,0 @@ - - - SelectImageDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 439 - 406 - - - - Select Image - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::LeftToRight - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 437 - 379 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 2 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp deleted file mode 100644 index 0a845216fe..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "BuilderResourceManifest.h" -#include "NewsShared/ResourceManagement/QtDownloadManager.h" -#include "NewsBuilder/S3Connector.h" -#include "UidGenerator.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsBuilder/ResourceManagement/UploadDescriptor.h" -#include "NewsBuilder/ResourceManagement/DeleteDescriptor.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsBuilder/ResourceManagement/ImageDescriptor.h" -#include "EndpointManager.h" - -#include -#include - -#include -#include - -namespace News { - - BuilderResourceManifest::BuilderResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback) - : ResourceManifest(syncSuccessCallback, syncFailCallback, syncUpdateCallback) - , m_s3Connector(new S3Connector) - , m_uidGenerator(new UidGenerator) - , m_endpointManager(new EndpointManager) {} - - - Resource* BuilderResourceManifest::AddArticle() - { - auto pResource = new Resource( - QString("%1").arg(m_uidGenerator->GenerateUid()), - "article"); - QJsonObject json; - json["title"] = "New Article"; - json["body"] = "Enter article body here"; - json["imageId"] = "0"; - QJsonDocument doc(json); - QByteArray data = doc.toJson(QJsonDocument::Compact).toStdString().data(); - pResource->SetData(data); - m_toUpload.push(pResource); - AppendResource(pResource); - m_order.append(pResource->GetId()); - return pResource; - } - - Resource* BuilderResourceManifest::AddImage(const QString& filename) - { - auto pResource = new Resource( - QString("%1").arg(m_uidGenerator->GenerateUid()), - "image"); - ImageDescriptor descriptor(*pResource); - QString error; - if (!descriptor.Read(filename, error)) - { - m_syncUpdateCallback(error, LogError); - delete pResource; - return nullptr; - } - m_toUpload.push(pResource); - AppendResource(pResource); - return pResource; - } - - void BuilderResourceManifest::UpdateResource(Resource* pResource) - { - if (!m_toUpload.contains(pResource)) - { - pResource->SetVersion(pResource->GetVersion() + 1); - m_toUpload.push(pResource); - } - } - - void BuilderResourceManifest::UseResource(const QString& id) - { - auto pResource = FindById(id, m_resources); - if (!pResource) - { - return; - } - pResource->SetRefCount(pResource->GetRefCount() + 1); - UpdateResource(pResource); - } - - void BuilderResourceManifest::FreeResource(const QString& id) - { - auto pResource = FindById(id, m_resources); - if (!pResource) - { - return; - } - if (m_toDelete.contains(pResource)) - { - return; - } - pResource->SetRefCount(pResource->GetRefCount() - 1); - if (pResource->GetRefCount() <= 0) - { - m_toDelete.push(pResource); - RemoveResource(pResource); - m_toUpload.removeAll(pResource); - - if (pResource->GetType().compare("article") == 0) - { - m_order.removeAll(pResource->GetId()); - } - } - else - { - m_toUpload.push(pResource); - } - } - - bool BuilderResourceManifest::UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error) - { - int index = m_order.indexOf(id); - if (index == -1) - { - m_syncUpdateCallback(QString("Couldn't find article: %1").arg(id), LogError); - error = ErrorCode::MissingArticle; - return false; - } - m_order.removeAll(id); - - index = index + (direction ? -1 : 1); - if (index < 0) - { - index = 0; - } - if (index > m_order.count()) - { - index = m_order.count(); - } - m_order.insert(index, id); - return true; - } - - EndpointManager* BuilderResourceManifest::GetEndpointManager() const - { - return m_endpointManager; - } - - void BuilderResourceManifest::Sync() - { - if (!m_endpointManager->GetSelectedEndpoint()) - { - FailSync(ErrorCode::NoEndpoint); - return; - } - if (!InitS3Connector()) - { - FailSync(ErrorCode::S3Fail); - return; - } - ResourceManifest::Sync(); - } - - void BuilderResourceManifest::Reset() - { - if (s_syncing) - { - m_syncUpdateCallback("Sync is already running", LogError); - return; - } - - m_toUpload.clear(); - - for (auto pResource : m_toDelete) - { - delete pResource; - } - m_toDelete.clear(); - - m_uidGenerator->Clear(); - - ResourceManifest::Reset(); - } - - void BuilderResourceManifest::PersistLocalResources() - { - // we are switching to another manifest here, while having the local data still present - // so we need to explicitly mark it for uploading so that it does not get deleted - for (auto pResource : m_resources) - { - if (!m_toUpload.contains(pResource)) - { - m_toUpload.push(pResource); - } - } - } - - void BuilderResourceManifest::SetSyncType(SyncType syncType) - { - m_syncType = syncType; - } - - bool BuilderResourceManifest::HasChanges() const - { - return m_toUpload.count() > 0 || m_toDelete.count() > 0; - } - - void BuilderResourceManifest::AppendResource(Resource* pResource) - { - m_uidGenerator->AddUid(pResource->GetId().toInt()); - ResourceManifest::AppendResource(pResource); - } - - void BuilderResourceManifest::RemoveResource(Resource* pResource) - { - m_uidGenerator->RemoveUid(pResource->GetId().toInt()); - ResourceManifest::RemoveResource(pResource); - } - - void BuilderResourceManifest::OnDownloadFail() - { - QMessageBox msgBox(QMessageBox::Critical, - "Sync failed", - QString("%1\n\n%2") - .arg(GetErrorMessage(ErrorCode::ManifestDownloadFail)) - .arg(QObject::tr("Overwrite resource manifest?")), - QMessageBox::Yes | QMessageBox::No); - if (msgBox.exec() == QMessageBox::Yes) - { - if (!UploadManifest()) - { - m_failed = true; - m_errorCode = ErrorCode::ManifestUploadFail; - } - } - ResourceManifest::OnDownloadFail(); - } - - //! This function overrides ResourceManifest Read and tries to do some minimal version checking - //! NOTE: version checking is not done yet, this needs a lot more work to version check properly - ErrorCode BuilderResourceManifest::Read(const QJsonObject& json) - { - int version = json["version"].toInt(); - if (version > m_version && m_syncType == SyncType::Verify) - { - return ErrorCode::OutOfSync; - } - - m_version = version; - QJsonArray resourceArray = json["resources"].toArray(); - - // initially mark ALL existing resource for deletion - QList toDelete = m_resources; - - for (auto resourceDoc : resourceArray) - { - auto pNewResource = new Resource(resourceDoc.toObject()); - // find local resource with the same id as new resource - auto pOldResource = FindById(pNewResource->GetId(), m_resources); - // if resource with the same id already exists then check its version - if (pOldResource) - { - // local resource is outdated, keep its in delete list, and download new one instead - if (pNewResource->GetVersion() > pOldResource->GetVersion()) - { - if (m_syncType == SyncType::Merge) - { - m_toDownload.push(pNewResource); - } - else if (m_syncType == SyncType::Overwrite) - { - m_toDelete.push(pNewResource); - } - } - // local resource is newer or same version, keep it (remove from toDelete list) - // and don't need to download new one - else - { - delete pNewResource; - toDelete.removeAll(pOldResource); - } - } - else - { - // if remote resource was NOT deleted locally then download it - if (!FindById(pNewResource->GetId(), m_toDelete)) - { - if (m_syncType == SyncType::Merge) - { - m_toDownload.push(pNewResource); - } - else if (m_syncType == SyncType::Overwrite) - { - m_toDelete.push(pNewResource); - } - } - // otherwise user deleted it... needs version check here - else - { - delete pNewResource; - } - } - } - - for (auto pResource : m_toUpload) - { - toDelete.removeAll(pResource); - } - - for (auto pResource : toDelete) - { - RemoveResource(pResource); - m_toDelete.removeAll(pResource); - delete pResource; - } - - //! Sync article display order - //! this is more complex to implement because articles may have been added or deleted - //! remotely by another developer while newsbuilder was running - //! for now just overwrite s3 version - QJsonArray orderArray = json["order"].toArray(); - for (auto idObject : orderArray) - { - QString id = idObject.toString(); - if (FindById(id, m_toDownload) && !m_order.contains(id)) - { - m_order.append(id); - } - } - return ErrorCode::None; - } - - //! Write resource manifest to JSON - void BuilderResourceManifest::Write(QJsonObject& json) const - { - QJsonArray resourceArray; - foreach(auto pResource, m_resources) - { - QJsonObject resourceObject; - pResource->Write(resourceObject); - resourceArray.append(resourceObject); - } - json["resources"] = resourceArray; - - QJsonArray orderArray; - foreach(auto id, m_order) - { - orderArray.append(id); - } - json["order"] = orderArray; - json["version"] = m_version; - } - - //! Figure out how many resources need to be synced - void BuilderResourceManifest::PrepareForSync() - { - // if resource is locally marked for deletion, then we don't need to upload/download it - for (auto pResource : m_toDelete) - { - m_toDownload.removeAll(pResource); - m_toUpload.removeAll(pResource); - } - - m_syncLeft = - m_toDownload.size() + - m_toUpload.size() + - m_toDelete.size(); - } - - void BuilderResourceManifest::SyncResources() - { - ResourceManifest::SyncResources(); - UploadResources(); - DeleteResources(); - } - - void BuilderResourceManifest::UploadResources() - { - QStack failures; - while (m_toUpload.count() > 0) - { - m_syncUpdateCallback( - QString("Uploading: %1 resources left").arg(m_toUpload.count()), - LogInfo); - - auto pResource = m_toUpload.pop(); - - auto uploadDescriptor = UploadDescriptor(*pResource); - uploadDescriptor.Upload(*m_s3Connector, - [&](QString url) - { - UpdateSync(); - }, - [&, pResource](QString error) - { - failures.push(pResource); - m_failed = true; - UpdateSync(); - m_syncUpdateCallback( - error, - LogError); - }); - } - while (failures.count() > 0) - { - m_toUpload.push(failures.pop()); - } - } - - void BuilderResourceManifest::DeleteResources() - { - while (m_toDelete.count() > 0) - { - m_syncUpdateCallback( - QString("Deleting: %1 resources left").arg(m_toDelete.count()), - LogInfo); - - auto pResource = m_toDelete.pop(); - - auto deleteDescriptor = DeleteDescriptor(*pResource); - deleteDescriptor.Delete(*m_s3Connector, - [&, pResource]() - { - delete pResource; - UpdateSync(); - }, - [&, pResource](QString error) - { - m_failed = true; - delete pResource; - UpdateSync(); - m_syncUpdateCallback( - QString("Failed to delete resource: %1").arg(error), - LogError); - }); - } - } - - void BuilderResourceManifest::FinishSync() - { - if (!m_failed) - { - QString error; - if (!UploadManifest()) - { - m_failed = true; - m_errorCode = ErrorCode::ManifestUploadFail; - } - } - ResourceManifest::FinishSync(); - } - - bool BuilderResourceManifest::UploadManifest() - { - m_syncUpdateCallback(QObject::tr("%1 to %2") - .arg("Uploading manifest") - .arg(m_endpointManager->GetSelectedEndpoint()->GetBucket()), - LogInfo); - m_version++; - Aws::String awsError; - QJsonObject manifestObject; - Write(manifestObject); - QJsonDocument doc(manifestObject); - auto ss = Aws::MakeShared( - S3Connector::ALLOCATION_TAG, - std::ios::in | std::ios::out | std::ios::binary); - *ss << QString(doc.toJson(QJsonDocument::Compact)).toStdString(); - Aws::String url; - if (!m_s3Connector->PutObject("resourceManifest", ss, url, awsError)) - { - m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError); - return false; - } - return true; - } - - bool BuilderResourceManifest::InitS3Connector() const - { - auto awsProfileName = - m_endpointManager->GetSelectedEndpoint()->GetAwsProfile(); - auto bucketName = - m_endpointManager->GetSelectedEndpoint()->GetBucket(); - Aws::String awsError; - if (!m_s3Connector->Init( - awsProfileName.toStdString().c_str(), - bucketName.toStdString().c_str(), - awsError)) - { - m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError); - return false; - } - return true; - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h b/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h deleted file mode 100644 index b6c20df571..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/ResourceManifest.h" - -#include - -class QJsonObject; - -namespace News -{ - class EndpointManager; - class ArticleDescriptor; - class UidGenerator; - class S3Connector; - class QtDownloadManager; - class Descriptor; - class DownloadDescriptor; - class Resource; - - //! Type of sync behavior - enum class SyncType - { - Merge, // merge resources from both endpoints, i.e. replacing outdated and appending missing (also normal sync behavior) - Overwrite, // overwrite resources on new endpoint with old endpoint - Verify // attempt to publish changes but abort if out of sync - }; - - //! Adds news-builder functionality layer to resource manager - class BuilderResourceManifest - : public ResourceManifest - { - public: - explicit BuilderResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback); - - //! Create new article resource - /*! - Create new article with default parameters, - Add it to resource collection, - Mark it for upload. - - \retval Resource * - a pointer to an article Resource - */ - Resource* AddArticle(); - - //! Create new image resource - /*! - Create new image from file, - add it to resource collection, - mark it for upload. - - \param filename - path to an image on hard drive - \retval Resource * - a pointer to an image Resource - */ - Resource* AddImage(const QString& filename); - - //! If resource was modified, add it to upload list and increment its version - void UpdateResource(Resource* resource); - - //! When resource is used by several other resources, this function is called - //! to increment its ref count - void UseResource(const QString& id); - - //! When resource is no longer used by another resource - //! decrement refCount, - //! if nothing else is using it, then mark for delete - void FreeResource(const QString& id); - - //! Move article either up or down in order queue - bool UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error); - - EndpointManager* GetEndpointManager() const; - - void Sync() override; - - void Reset() override; - - //! When switching endpoints Merge allows to persist resources to another endpoint, - //! thus copying news from one location to another upon next Sync - void PersistLocalResources(); - - void SetSyncType(SyncType syncType); - - //! Are there local changes - bool HasChanges() const; - - protected: - void AppendResource(Resource* pResource) override; - void RemoveResource(Resource* pResource) override; - void OnDownloadFail() override; - void FinishSync() override; - - private: - S3Connector* m_s3Connector = nullptr; - UidGenerator* m_uidGenerator = nullptr; - EndpointManager* m_endpointManager = nullptr; - SyncType m_syncType = SyncType::Merge; - - QStack m_toUpload; - QStack m_toDelete; - - ErrorCode Read(const QJsonObject& json) override; - void Write(QJsonObject& json) const; - - void PrepareForSync() override; - void SyncResources() override; - - void UploadResources(); - void DeleteResources(); - - bool UploadManifest(); - - //! Initializes S3 connector with selected endpoint - bool InitS3Connector() const; - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp deleted file mode 100644 index 63cdb46218..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "DeleteDescriptor.h" -#include "NewsBuilder/S3Connector.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include - -namespace News -{ - - DeleteDescriptor::DeleteDescriptor(Resource& resource) - : Descriptor(resource) {} - - void DeleteDescriptor::Delete(S3Connector& s3Connector, - std::function deleteSuccessCallback, - std::function deleteFailCallback) const - { - Aws::String error; - if (!s3Connector.DeleteObject( - m_resource.GetId().toStdString().c_str(), - error)) - { - deleteFailCallback(QString("Error deleting resource %1: %2") - .arg(m_resource.GetId()) - .arg(error.c_str())); - } - else - { - deleteSuccessCallback(); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h deleted file mode 100644 index 8928e9e19d..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/Descriptor.h" - -#include -#include - -namespace News -{ - class S3Connector; - - class DeleteDescriptor - : public Descriptor - { - public: - explicit DeleteDescriptor(Resource& resource); - - void Delete(S3Connector& s3Connector, - std::function deleteSuccessCallback, - std::function deleteFailCallback) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp deleted file mode 100644 index a16ec48851..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ImageDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include -#include -#include -#include -#include - -namespace News -{ - - ImageDescriptor::ImageDescriptor( - Resource& resource) - : Descriptor(resource) - { - } - - bool ImageDescriptor::Read(const QString& filename, QString& error) const - { - QImageReader reader(filename); - if (!reader.canRead()) - { - error = reader.errorString(); - return false; - } - QImage image = reader.read(); - - QPixmap pixmap(filename); - QByteArray data; - QBuffer buffer(&data); - buffer.open(QIODevice::WriteOnly); - QFile test("test.png"); - if (pixmap.save(&buffer, "PNG")) - { - m_resource.SetData(data); - return true; - } - error = QString("failed to save image %1").arg(filename); - return false; - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h deleted file mode 100644 index ba4533b0c0..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -class QString; - -namespace News -{ - class ImageDescriptor - : public Descriptor - { - public: - explicit ImageDescriptor(Resource& resource); - - bool Read(const QString& filename, QString& error) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp deleted file mode 100644 index 699959ed85..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "NewsBuilder/S3Connector.h" -#include "UploadDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include -#include -#include - -#include - -namespace News -{ - - UploadDescriptor::UploadDescriptor(Resource& resource) - : Descriptor(resource) {} - - void UploadDescriptor::Upload(S3Connector& s3Connector, - std::function uploadSuccessCallback, - std::function uploadFailCallback) const - { - Aws::String error; - - auto ss = - Aws::MakeShared(S3Connector::ALLOCATION_TAG, - std::ios::in | std::ios::out | std::ios::binary); - auto* pbuf = ss->rdbuf(); - pbuf->sputn(m_resource.GetData().data(), m_resource.GetData().size()); - Aws::String awsUrl; - - if (!s3Connector.PutObject( - m_resource.GetId().toStdString().c_str(), - ss, - m_resource.GetData().size(), - awsUrl, - error)) - { - uploadFailCallback(QObject::tr("Error uploading resource %1: %2") - .arg(m_resource.GetId()) - .arg(error.c_str())); - } - else - { - uploadSuccessCallback(QString(awsUrl.c_str())); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h deleted file mode 100644 index 71a7732c1e..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/Descriptor.h" - -#include -#include - -namespace News -{ - class S3Connector; - - class UploadDescriptor - : public Descriptor - { - public: - explicit UploadDescriptor(Resource& resource); - - void Upload(S3Connector& s3Connector, - std::function uploadSuccessCallback, - std::function uploadFailCallback) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss b/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss deleted file mode 100644 index 01ca308585..0000000000 --- a/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss +++ /dev/null @@ -1,44 +0,0 @@ -QLabel -{ - font-size: 12px; - color: #FFFFFF; - line-height: 20px; - background-color: transparent; - margin: 0; -} - -QLabel#titleLabel -{ - font-size: 22px; - line-height: 32px; -} - -QLabel#bodyLabel -{ - font-size: 14px; - line-height: 20px; -} - -QFrame#viewContainer[articleStyle="pinned"] -{ - background: rgba(180,139,255,5%); - border: 1px solid #B48BFF; - box-shadow: 0 0 4px 0 rgba(0,0,0,50%); -} - -QWidget#articleViewContainerRoot -{ - background: #222222; -} - -QScrollArea#previewArea, -QWidget#articleViewContents, -QFrame#imageFrame -{ - background-color: transparent; -} - -News--ArticleView.SelectedArticle > QWidget -{ - background: #333333; -} diff --git a/Code/Tools/News/NewsBuilder/Resources/missing-image.png b/Code/Tools/News/NewsBuilder/Resources/missing-image.png deleted file mode 100644 index 889493e628..0000000000 --- a/Code/Tools/News/NewsBuilder/Resources/missing-image.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4255a25636d77a54809592bc98bef47fa9044be03cd65d73daa821711489e00f -size 7379 diff --git a/Code/Tools/News/NewsBuilder/S3Connector.cpp b/Code/Tools/News/NewsBuilder/S3Connector.cpp deleted file mode 100644 index a54b6fa8f8..0000000000 --- a/Code/Tools/News/NewsBuilder/S3Connector.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "S3Connector.h" - -#include -#include -#include - - -AZ_PUSH_DISABLE_WARNING(4251 4819, "-Wunknown-warning-option") // Invalid character not in default code page -#include -#include -#include -#include -#include -#include -#include -#include -AZ_POP_DISABLE_WARNING - -namespace News -{ - const char* S3Connector::ALLOCATION_TAG = "NewsBuilder"; - - S3Connector::S3Connector() - : m_s3Client(nullptr) - , m_limiter(nullptr) - , m_valid(false) - { - } - - S3Connector::~S3Connector() {} - - bool S3Connector::Init(const char* awsProfileName, const char* bucket, Aws::String& error) - { - Aws::SDKOptions options; - options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace; - Aws::InitAPI(options); - - Aws::Client::ClientConfiguration config; - config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED; - config.scheme = Aws::Http::Scheme::HTTPS; - config.connectTimeoutMs = 30000; - config.requestTimeoutMs = 30000; - config.readRateLimiter = m_limiter; - config.writeRateLimiter = m_limiter; - - auto provider = - Aws::MakeShared( - ALLOCATION_TAG, - awsProfileName); - - auto accessKeyId = provider->GetAWSCredentials().GetAWSAccessKeyId(); - - //! verify that credential file exists - if (accessKeyId.empty()) - { - error = "LY_NEWS_DEVELOPER AWS credentials not found. Add credentials in LY Editor AWS->ClientManager"; - m_valid = false; - return false; - } - - m_bucket = Aws::String(bucket); - m_s3Client = Aws::MakeShared( - ALLOCATION_TAG, - provider, - config); - - m_valid = true; - return true; - } - - bool S3Connector::GetObject(const char* key, - Aws::String& data, - Aws::String& url, - Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::GetObjectRequest getObjectRequest; - getObjectRequest.SetBucket(m_bucket); - getObjectRequest.SetKey(key); - auto outcome = m_s3Client->GetObject(getObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET); - Aws::StringStream ss; - ss << outcome.GetResult().GetBody().rdbuf(); - data = ss.str(); - return true; - } - - bool S3Connector::PutObject(const char* key, - STREAM_PTR stream, - Aws::String& url, - Aws::String& error) const - { - return PutObject(key, stream, GetStreamLength(stream), url, error); - } - - bool S3Connector::PutObject(const char* key, - STREAM_PTR stream, - int length, - Aws::String& url, - Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::PutObjectRequest putObjectRequest; - putObjectRequest.SetBucket(m_bucket); - putObjectRequest.SetBody(stream); - putObjectRequest.SetContentLength(length); - putObjectRequest.SetContentMD5( - Aws::Utils::HashingUtils::Base64Encode( - Aws::Utils::HashingUtils::CalculateMD5(*putObjectRequest.GetBody()))); - putObjectRequest.SetContentType(Aws::String("binary/octet-stream")); - putObjectRequest.SetKey(key); - putObjectRequest.SetACL(Aws::S3::Model::ObjectCannedACL::public_read); - auto outcome = m_s3Client->PutObject(putObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET); - return true; - } - - bool S3Connector::DeleteObject(const char* key, Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::DeleteObjectRequest deleteObjectRequest; - deleteObjectRequest.SetBucket(m_bucket); - deleteObjectRequest.SetKey(key); - auto outcome = m_s3Client->DeleteObject(deleteObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - return true; - } - - int S3Connector::GetStreamLength(STREAM_PTR stream) - { - stream->seekg(0, std::ios::end); - auto length = stream->tellg(); - stream->seekg(0, std::ios::beg); - return static_cast(length); - } - -} diff --git a/Code/Tools/News/NewsBuilder/S3Connector.h b/Code/Tools/News/NewsBuilder/S3Connector.h deleted file mode 100644 index d0404bfddb..0000000000 --- a/Code/Tools/News/NewsBuilder/S3Connector.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") // includes ppltasks.h which throws a C4355 warning: 'this' used in base member initializer list -#include -AZ_POP_DISABLE_WARNING - -typedef std::shared_ptr STREAM_PTR; - -namespace News -{ - //! A light wrapper around AWS SDK - class S3Connector - { - public: - static const char* ALLOCATION_TAG; - - S3Connector(); - ~S3Connector(); - - //! Make s3 client using credentials stored in [user]/.aws/credentials file - /*! - \param awsProfileName - name of AWS credentials - \param bucket - name of s3 bucket to use for AWS operations - \param error - error string - \retval bool - true if success else false - */ - bool Init(const char* awsProfileName, const char* bucket, Aws::String& error); - - bool GetObject(const char* key, - Aws::String& data, - Aws::String& url, - Aws::String& error) const; - - bool PutObject(const char* key, - STREAM_PTR stream, - Aws::String& url, - Aws::String& error) const; - - bool PutObject(const char* key, - STREAM_PTR stream, - int length, - Aws::String& url, - Aws::String& error) const; - - bool DeleteObject(const char* key, - Aws::String& error) const; - - private: - Aws::String m_bucket; - std::shared_ptr m_s3Client; - std::shared_ptr m_limiter; - bool m_valid; - - static int GetStreamLength(STREAM_PTR stream); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/UidGenerator.cpp b/Code/Tools/News/NewsBuilder/UidGenerator.cpp deleted file mode 100644 index 060f593996..0000000000 --- a/Code/Tools/News/NewsBuilder/UidGenerator.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "UidGenerator.h" - -#include - -namespace News -{ - - UidGenerator::UidGenerator() - { - srand(static_cast(time(nullptr))); - } - - int UidGenerator::GenerateUid() - { - int uid; - do - { - uid = rand(); - } - while (std::find(m_uids.begin(), m_uids.end(), uid) != m_uids.end()); - m_uids.push_back(uid); - return uid; - } - - int UidGenerator::AddUid(int uid) - { - if (std::find(m_uids.begin(), m_uids.end(), uid) == m_uids.end()) - { - m_uids.push_back(uid); - } - return uid; - } - - void UidGenerator::RemoveUid(int uid) - { - auto it = std::find(m_uids.begin(), m_uids.end(), uid); - if (it != m_uids.end()) - { - m_uids.erase(it); - } - } - - void UidGenerator::Clear() - { - m_uids.clear(); - } - -} diff --git a/Code/Tools/News/NewsBuilder/UidGenerator.h b/Code/Tools/News/NewsBuilder/UidGenerator.h deleted file mode 100644 index 825df9e340..0000000000 --- a/Code/Tools/News/NewsBuilder/UidGenerator.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace News -{ - //! A simple unique id generator. - class UidGenerator - { - public: - UidGenerator(); - int GenerateUid(); - int AddUid(int uid); - void RemoveUid(int uid); - void Clear(); - - private: - std::vector m_uids; - }; -} diff --git a/Code/Tools/News/NewsBuilder/main.cpp b/Code/Tools/News/NewsBuilder/main.cpp deleted file mode 100644 index 6a43c681b1..0000000000 --- a/Code/Tools/News/NewsBuilder/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -#include "Qt/NewsBuilder.h" -#include -#include -#include -#include - - -int main(int argc, char *argv[]) -{ - // Must be set before QApplication is initialized, so that we support HighDpi monitors, like the Retina displays - // on Windows 10 - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - - QApplication a(argc, argv); - AZ::IO::FixedMaxPath engineRootPath; - { - AZ::ComponentApplication componentApplication; - auto settingsRegistry = AZ::SettingsRegistry::Get(); - settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder); - } - News::NewsBuilder w(nullptr, engineRootPath); - w.show(); - return a.exec(); -} diff --git a/Code/Tools/News/NewsBuilder/news_builder.qrc b/Code/Tools/News/NewsBuilder/news_builder.qrc deleted file mode 100644 index 010ac598f1..0000000000 --- a/Code/Tools/News/NewsBuilder/news_builder.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Resources/NewsBuilder.qss - - diff --git a/Code/Tools/News/NewsBuilder/news_builder_files.cmake b/Code/Tools/News/NewsBuilder/news_builder_files.cmake deleted file mode 100644 index c46e66a357..0000000000 --- a/Code/Tools/News/NewsBuilder/news_builder_files.cmake +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - main.cpp - S3Connector.cpp - S3Connector.h - UidGenerator.cpp - UidGenerator.h - EndpointManager.cpp - EndpointManager.h - Qt/ArticleDetails.cpp - Qt/ArticleDetails.h - Qt/ArticleDetails.ui - Qt/ArticleDetailsContainer.cpp - Qt/ArticleDetailsContainer.h - Qt/ArticleDetailsContainer.ui - Qt/AwsDialog.ui - Qt/BuilderArticleViewContainer.cpp - Qt/BuilderArticleViewContainer.h - Qt/BuilderArticleViewContainer.ui - Qt/EndpointEntryView.cpp - Qt/EndpointEntryView.h - Qt/EndpointEntryView.ui - Qt/EndpointManagerView.cpp - Qt/EndpointManagerView.h - Qt/EndpointManagerView.ui - Qt/ImageItem.cpp - Qt/ImageItem.h - Qt/ImageItem.ui - Qt/LogContainer.cpp - Qt/LogContainer.h - Qt/LogContainer.ui - Qt/NewsBuilder.cpp - Qt/NewsBuilder.h - Qt/Newsbuilder.qrc - Qt/Newsbuilder.ui - Qt/QCustomMessageBox.cpp - Qt/QCustomMessageBox.h - Qt/QCustomMessageBox.ui - Qt/SelectImage.cpp - Qt/SelectImage.h - Qt/SelectImage.ui - ResourceManagement/BuilderResourceManifest.cpp - ResourceManagement/BuilderResourceManifest.h - ResourceManagement/DeleteDescriptor.cpp - ResourceManagement/DeleteDescriptor.h - ResourceManagement/ImageDescriptor.cpp - ResourceManagement/ImageDescriptor.h - ResourceManagement/UploadDescriptor.cpp - ResourceManagement/UploadDescriptor.h -) - -set(SKIP_UNITY_BUILD_INCLUSION_FILES - # Fix for unity causing the 'News::BuilderResourceManifest::UpdateResourceA' symbol to be unresolved - Qt/ArticleDetails.cpp - # Fix for unity causing the ' Aws::S3::S3Client::GetObjectA' symbol to be unresolved - S3Connector.cpp - -) diff --git a/Code/Tools/News/NewsShared/ErrorCodes.h b/Code/Tools/News/NewsShared/ErrorCodes.h deleted file mode 100644 index 444e0c6f67..0000000000 --- a/Code/Tools/News/NewsShared/ErrorCodes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace News -{ - enum class ErrorCode : int - { - None, - OutOfSync, - ManifestDownloadFail, - FailedToSync, - AlreadySyncing, - FailedToParseManifest, - MissingArticle, - NoEndpoint, - ManifestUploadFail, - S3Fail - }; - - inline extern const char* GetErrorMessage(ErrorCode errorCode) - { - static const char* errors[] - { - "", - "Your manifest is out of sync. Reopen the same endpoint and sync to resolve the conflict and try again.", - "Failed to download resource manifest", - "Failed to sync resources", - "Sync is already running", - "Failed to parse resource manifest", - "Could not find article, try syncing again", - "Missing or incorrect endpoint selected", - "Failed to upload resource manifest", - "Failed to init S3 connection" - }; - int errorCount = sizeof errors / sizeof errors[0]; - int typeIndex = static_cast(errorCode); - if (typeIndex < 0 || typeIndex >= errorCount) - { - return "Invalid error code"; - } - return errors[typeIndex]; - } -} // namespace News diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp deleted file mode 100644 index 6f2a7e3c9c..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleErrorView.h" -#include "NewsShared/Qt/ui_ArticleErrorView.h" - -using namespace News; - -ArticleErrorView::ArticleErrorView( - QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::ArticleErrorViewWidget()) -{ - m_ui->setupUi(this); -} - -ArticleErrorView::~ArticleErrorView(){} - -#include "NewsShared/Qt/moc_ArticleErrorView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h deleted file mode 100644 index 3130690dc1..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ArticleErrorViewWidget; -} - -namespace AzQtComponents -{ - class ExtendedLabel; -} - -namespace News -{ - class ArticleErrorView - : public QWidget - { - Q_OBJECT - public: - ArticleErrorView(QWidget* parent); - ~ArticleErrorView(); - - private: - QScopedPointer m_ui; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui deleted file mode 100644 index c94c636720..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui +++ /dev/null @@ -1,239 +0,0 @@ - - - ArticleErrorViewWidget - - - - 0 - 0 - 192 - 228 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - ArticleView - - - background-color: none; text-align: left; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - border: none; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 14 - - - - - - - - 0 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 14 - 20 - - - - - - - - 0 - - - - - - 160 - 90 - - - - - - - :/images/Resources/ErrorImage.jpg - - - - 160 - 90 - - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - a { text-decoration: underline; color: red } - - - We couldn’t connect to the network or access our news database. To see the latest Open 3D Engine news, blogs, tutorials, and more, please visit the <a href="http://aws.amazon.com/lumberyard/">Lumberyard website</a>. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - true - - - Qt::LinksAccessibleByMouse - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 14 - 20 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - -
diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.cpp b/Code/Tools/News/NewsShared/Qt/ArticleView.cpp deleted file mode 100644 index 082a29d38a..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleView.h" - -#include - -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: '...' needs to have dll-interface to be used by clients of class '...' -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsShared/Qt/ui_ArticleView.h" -#include "NewsShared/Qt/ui_PinnedArticleView.h" -#include "NewsShared/ResourceManagement/ResourceManifest.h" -#include "NewsShared/ResourceManagement/Resource.h" - - -#include -#include -AZ_POP_DISABLE_WARNING - -using namespace News; - -ArticleView::ArticleView( - QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : QWidget(parent) - , m_pArticle(new ArticleDescriptor(article)) - , m_manifest(manifest) - , m_icon(nullptr) -{ - -} - -void ArticleView::Update() -{ - Q_ASSERT(m_widgetImageFrame && m_widgetTitle && m_widgetBody); - - auto pResource = m_manifest.FindById(m_pArticle->GetResource().GetId()); - m_pArticle.reset(); - if (pResource) - { - m_pArticle = QSharedPointer(new ArticleDescriptor(*pResource)); - m_widgetTitle->setText(m_pArticle->GetTitle()); - m_widgetBody->setText(m_pArticle->GetBody()); - auto pImageResource = m_manifest.FindById(m_pArticle->GetImageId()); - if (pImageResource) - { - QPixmap pixmap; - if (pixmap.loadFromData(pImageResource->GetData())) - { - if (!m_icon) - { - m_icon = new AzQtComponents::ExtendedLabel(this); - m_icon->setStyleSheet("border: none;"); - m_icon->setAlignment(Qt::AlignCenter); - static_cast( - m_widgetImageFrame->layout())->insertWidget(0, m_icon); - connect(m_icon, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - } - m_icon->setPixmap(pixmap.scaled(m_widgetImageFrame->minimumWidth(), - m_widgetImageFrame->minimumHeight(), - Qt::KeepAspectRatioByExpanding)); - } - else - { - RemoveIcon(); - } - } - else - { - RemoveIcon(); - } - } -} - -void ArticleView::mousePressEvent([[maybe_unused]] QMouseEvent* event) -{ - articleSelectedSlot(); -} - -void ArticleView::RemoveIcon() -{ - if (m_icon) - { - delete m_icon; - m_icon = nullptr; - } -} - -void ArticleView::linkActivatedSlot(const QString& link) -{ - QDesktopServices::openUrl(QUrl(link)); - Q_EMIT linkActivatedSignal(link); -} - -void ArticleView::articleSelectedSlot() -{ - Q_EMIT articleSelectedSignal(m_pArticle->GetResource().GetId()); -} - -QSharedPointer ArticleView::GetArticle() const -{ - return m_pArticle; -} - -void ArticleView::SetupViewWidget(QFrame* widgetImageFrame, AzQtComponents::ExtendedLabel* widgetTitle, AzQtComponents::ExtendedLabel* widgetBody) -{ - Q_ASSERT(m_widgetImageFrame == nullptr && m_widgetTitle == nullptr && m_widgetBody == nullptr); - - m_widgetImageFrame = widgetImageFrame; - m_widgetTitle = widgetTitle; - m_widgetBody = widgetBody; - - connect(m_widgetTitle, &QLabel::linkActivated, this, &ArticleView::linkActivatedSlot); - connect(m_widgetBody, &QLabel::linkActivated, this, &ArticleView::linkActivatedSlot); - connect(m_widgetTitle, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - connect(m_widgetBody, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - - Q_ASSERT(m_widgetImageFrame && m_widgetTitle && m_widgetBody); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ArticleViewDefaultWidget -//////////////////////////////////////////////////////////////////////////////////////////////////// -ArticleViewDefaultWidget::ArticleViewDefaultWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : ArticleView(parent, article, manifest) - , m_ui(new Ui::ArticleViewWidget()) -{ - m_ui->setupUi(this); - SetupViewWidget(m_ui->imageFrame, m_ui->titleLabel, m_ui->bodyLabel); - Update(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ArticleViewPinnedWidget -//////////////////////////////////////////////////////////////////////////////////////////////////// -ArticleViewPinnedWidget::ArticleViewPinnedWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : ArticleView(parent, article, manifest) - , m_ui(new Ui::PinnedArticleViewWidget()) -{ - m_ui->setupUi(this); - SetupViewWidget(m_ui->imageFrame, m_ui->titleLabel, m_ui->bodyLabel); - Update(); -} - -#include "NewsShared/Qt/moc_ArticleView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.h b/Code/Tools/News/NewsShared/Qt/ArticleView.h deleted file mode 100644 index 16a29732f0..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ArticleViewWidget; - class PinnedArticleViewWidget; -} - -namespace AzQtComponents -{ - class ExtendedLabel; -} - -class QFrame; - -namespace News -{ - class ArticleDescriptor; - class ResourceManifest; - - class ArticleView - : public QWidget - { - Q_OBJECT - public: - ArticleView(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleView() = default; - - void Update(); - QSharedPointer GetArticle() const; - - Q_SIGNALS: - void articleSelectedSignal(QString resourceId); - void linkActivatedSignal(const QString& link); - - protected: - void SetupViewWidget(QFrame* widgetImageFrame, AzQtComponents::ExtendedLabel* widgetTitle, AzQtComponents::ExtendedLabel* widgetBody); - void mousePressEvent(QMouseEvent* event); - - private: - - QFrame* m_widgetImageFrame = nullptr; - AzQtComponents::ExtendedLabel* m_widgetTitle = nullptr; - AzQtComponents::ExtendedLabel* m_widgetBody = nullptr; - AzQtComponents::ExtendedLabel* m_icon = nullptr; - - QSharedPointer m_pArticle; - const ResourceManifest& m_manifest; - - void RemoveIcon(); - - private Q_SLOTS: - void linkActivatedSlot(const QString& link); - void articleSelectedSlot(); - }; - - class ArticleViewDefaultWidget : public ArticleView - { - public: - ArticleViewDefaultWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleViewDefaultWidget() = default; - - private: - Ui::ArticleViewWidget* m_ui = nullptr; - }; - - class ArticleViewPinnedWidget : public ArticleView - { - public: - ArticleViewPinnedWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleViewPinnedWidget() = default; - - private: - Ui::PinnedArticleViewWidget* m_ui = nullptr; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.ui b/Code/Tools/News/NewsShared/Qt/ArticleView.ui deleted file mode 100644 index 67d1d8857b..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.ui +++ /dev/null @@ -1,244 +0,0 @@ - - - ArticleViewWidget - - - - 0 - 0 - 430 - 376 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - default - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 430 - 184 - - - - - 430 - 184 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Title: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 12 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Body - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 0 - - - 0 - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 24 - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp deleted file mode 100644 index 1d718d1bb8..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleViewContainer.h" -#include "ArticleView.h" -#include "NewsShared/ResourceManagement/ResourceManifest.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsShared/Qt/ArticleErrorView.h" -#include "NewsShared/Qt/KeepInTouchView.h" -#include "NewsShared/Qt/ui_ArticleViewContainer.h" - -#include -#include - -namespace News -{ - - ArticleViewContainer::ArticleViewContainer(QWidget* parent, ResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleViewContainerWidget) - , m_manifest(manifest) - , m_loadingLabel(nullptr) - , m_errorMessage(nullptr) - { - m_ui->setupUi(this); - AddLoadingMessage(); - - m_keepInTouchViewWidget = new KeepInTouchView(this); - m_keepInTouchViewWidget->setVisible(false); - connect(m_keepInTouchViewWidget, &KeepInTouchView::linkActivatedSignal, - this, &ArticleViewContainer::linkActivatedSignal); - } - - ArticleViewContainer::~ArticleViewContainer() {} - - void ArticleViewContainer::PopulateArticles() - { - Clear(); - - bool articlesFound = false; - for (auto id : m_manifest.GetOrder()) - { - auto pResource = m_manifest.FindById(id); - if (pResource && pResource->GetType().compare("article") == 0) - { - AddArticleView(ArticleDescriptor(*pResource)); - articlesFound = true; - } - } - - if (!articlesFound) - { - AddErrorMessage(); - } - else - { - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(layout->count() - 1, m_keepInTouchViewWidget); - m_keepInTouchViewWidget->setVisible(true); - } - - qApp->processEvents(); - } - - ArticleView* ArticleViewContainer::FindById(const QString& id) - { - auto it = std::find_if( - m_articles.begin(), - m_articles.end(), - [id](ArticleView* articleView) -> bool - { - if (!articleView) - { - return false; - } - return articleView->GetArticle()->GetResource().GetId().compare(id) == 0; - }); - if (it == m_articles.end()) - { - return nullptr; - } - return *it; - } - - void ArticleViewContainer::AddArticleView(const ArticleDescriptor& articleDesc, int articlePosition) - { - ClearError(); - - ArticleView* view = CreateArticleView(articleDesc); - if (view == nullptr) - { - return; - } - - m_articles.append(view); - - connect(view, &ArticleView::articleSelectedSignal, - this, &ArticleViewContainer::articleSelectedSlot); - connect(view, &ArticleView::linkActivatedSignal, - this, &ArticleViewContainer::linkActivatedSignal); - - auto layout = static_cast(m_ui->articleViewContents->layout()); - if (articlePosition == -1) - { - articlePosition = layout->count() - 1; - } - - layout->insertWidget(articlePosition, view); - qApp->processEvents(); - } - - void ArticleViewContainer::DeleteArticleView(ArticleView* view) - { - m_articles.removeAll(view); - m_ui->articleViewContents->layout()->removeWidget(view); - delete view; - } - - void ArticleViewContainer::ForceRefreshArticleView(ArticleView* articleView) - { - if (articleView == nullptr) - { - return; - } - - QSharedPointer articleDesc = articleView->GetArticle(); - auto layout = static_cast(m_ui->articleViewContents->layout()); - const int viewIndex = layout->indexOf(articleView); - - DeleteArticleView(articleView); - AddArticleView(*articleDesc, viewIndex); - } - - void ArticleViewContainer::ScrollToView(ArticleView* view) const - { - m_ui->previewArea->ensureWidgetVisible(view); - } - - void ArticleViewContainer::ClearError() - { - //delete loading label - if (m_loadingLabel) - { - delete m_loadingLabel; - m_loadingLabel = nullptr; - } - - //delete error message - if (m_errorMessage) - { - delete m_errorMessage; - m_errorMessage = nullptr; - } - } - - void ArticleViewContainer::articleSelectedSlot(QString id) - { - emit articleSelectedSignal(id); - } - - void ArticleViewContainer::UpdateArticleOrder(ArticleView* view, bool direction) const - { - QVBoxLayout* layout = qobject_cast(m_ui->articleViewContents->layout()); - - const int index = layout->indexOf(view); - - if (direction && index == 0) - { - return; - } - - if (!direction && index == layout->count() - 2) - { - return; - } - - const int newIndex = direction ? index - 1 : index + 1; - layout->removeWidget(view); - layout->insertWidget(newIndex, view); - } - - void ArticleViewContainer::AddLoadingMessage() - { - if (m_errorMessage) - { - delete m_errorMessage; - m_errorMessage = nullptr; - } - - if (!m_loadingLabel) - { - m_loadingLabel = new QLabel(this); - m_loadingLabel->setText("Retrieving news..."); - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(0, m_loadingLabel); - } - } - - void ArticleViewContainer::AddErrorMessage() - { - if (m_loadingLabel) - { - delete m_loadingLabel; - m_loadingLabel = nullptr; - } - - if (!m_errorMessage) - { - m_errorMessage = new ArticleErrorView(this); - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(0, m_errorMessage); - } - } - - void ArticleViewContainer::Clear() - { - ClearError(); - - for (auto articleView : m_articles) - { - delete articleView; - } - - m_articles.clear(); - } - - ArticleViewContainer::ArticleStyle ArticleViewContainer::GetArticleStyleEnumFromString(const QString& articleStyleStr) const - { - static const QMap articleStyleStringEnumMap = { - { "default", ArticleStyle::Default }, - { "pinned", ArticleStyle::Pinned } - }; - - if (articleStyleStringEnumMap.contains(articleStyleStr) == false) - { - Q_ASSERT(false); - return ArticleStyle::Default; - } - - return articleStyleStringEnumMap.value(articleStyleStr); - } - - ArticleView* ArticleViewContainer::CreateArticleView(const ArticleDescriptor& articleDesc) - { - ArticleStyle articleStyle = GetArticleStyleEnumFromString(articleDesc.GetArticleStyle()); - - switch(articleStyle) - { - case ArticleStyle::Default: - return new ArticleViewDefaultWidget(this, articleDesc, m_manifest); - case ArticleStyle::Pinned: - return new ArticleViewPinnedWidget(this, articleDesc, m_manifest); - default: - Q_ASSERT(false); - return nullptr; - } - } - -} - -#include "NewsShared/Qt/moc_ArticleViewContainer.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h deleted file mode 100644 index c0ae3b2701..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include "NewsShared/LogType.h" - -#include -#include -#endif - -class QLabel; - -namespace Ui -{ - class ArticleViewContainerWidget; -} - -namespace News -{ - class Resource; - class ArticleView; - class ArticleDescriptor; - class ResourceManifest; - class ArticleErrorView; - class KeepInTouchView; - - class ArticleViewContainer - : public QWidget - { - Q_OBJECT - - enum ArticleStyle - { - Default, - Pinned - }; - - public: - explicit ArticleViewContainer(QWidget* parent, ResourceManifest& manifest); - ~ArticleViewContainer(); - - virtual void PopulateArticles(); - ArticleView* FindById(const QString& id); - void AddArticleView(const ArticleDescriptor& articleDesc, int articlePosition = -1); - void DeleteArticleView(ArticleView* view); - void ForceRefreshArticleView(ArticleView* articleView); - void ScrollToView(ArticleView* view) const; - void UpdateArticleOrder(ArticleView* view, bool direction) const; - void AddLoadingMessage(); - void AddErrorMessage(); - void Clear(); - - Q_SIGNALS: - void articleSelectedSignal(QString resourceId); - void addArticle(Resource* article); - void logSignal(QString text, LogType logType = LogInfo); - void scrolled(); - void linkActivatedSignal(const QString& link); - - private: - QScopedPointer m_ui; - QList m_articles; - ResourceManifest& m_manifest; - QLabel* m_loadingLabel; - ArticleErrorView* m_errorMessage; - KeepInTouchView* m_keepInTouchViewWidget = nullptr; - - void ClearError(); - ArticleStyle GetArticleStyleEnumFromString(const QString& articleStyleStr) const; - ArticleView* CreateArticleView(const ArticleDescriptor& articleDesc); - - private Q_SLOTS: - virtual void articleSelectedSlot(QString id); - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui deleted file mode 100644 index dfb71ea31f..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui +++ /dev/null @@ -1,104 +0,0 @@ - - - ArticleViewContainerWidget - - - - 0 - 0 - 606 - 753 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignHCenter|Qt::AlignTop - - - - - 0 - 0 - 589 - 753 - - - - - 16 - - - 15 - - - 15 - - - 15 - - - 15 - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - - - - - diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp deleted file mode 100644 index 43c32c43fc..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "KeepInTouchView.h" -#include "NewsShared/Qt/ui_KeepInTouchView.h" - -#include -#include -#include -#include - -namespace News -{ - KeepInTouchView::KeepInTouchView(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::KeepInTouchViewWidget()) - { - m_ui->setupUi(this); - - m_ui->twich_container->setCursor(Qt::PointingHandCursor); - m_ui->twitter_container->setCursor(Qt::PointingHandCursor); - m_ui->youtube_container->setCursor(Qt::PointingHandCursor); - m_ui->facebook_container->setCursor(Qt::PointingHandCursor); - - m_ui->twich_container->installEventFilter(this); - m_ui->twitter_container->installEventFilter(this); - m_ui->youtube_container->installEventFilter(this); - m_ui->facebook_container->installEventFilter(this); - } - - bool KeepInTouchView::eventFilter(QObject *watched, QEvent *event) - { - if (event->type() == QEvent::MouseButtonRelease) - { - if (watched == m_ui->twich_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Twitch); - } - else if (watched == m_ui->twitter_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Twitter); - } - else if (watched == m_ui->youtube_container) - { - return LaunchSocialMediaUrl(SocialMediaType::YouTube); - } - else if (watched == m_ui->facebook_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Facebook); - } - } - - return QWidget::eventFilter(watched, event); - } - - bool KeepInTouchView::LaunchSocialMediaUrl(SocialMediaType type) - { - static const QMap socialMediaTypeToUrlMap = - { - { SocialMediaType::Twitch, m_twitchUrl }, - { SocialMediaType::Twitter, m_twitterUrl }, - { SocialMediaType::YouTube, m_youtubeUrl }, - { SocialMediaType::Facebook, m_facebookUrl } - }; - - if (socialMediaTypeToUrlMap.contains(type) == false) - { - return false; - } - - QString link = socialMediaTypeToUrlMap[type]; - Q_EMIT linkActivatedSignal(link); - - return QDesktopServices::openUrl(QUrl(link)); - } -} - -#include "NewsShared/Qt/moc_KeepInTouchView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h deleted file mode 100644 index 5d5c6a9e36..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class KeepInTouchViewWidget; -} - -namespace News -{ - class KeepInTouchView - : public QWidget - { - Q_OBJECT - - enum class SocialMediaType - { - Twitch, - Twitter, - YouTube, - Facebook - }; - - public: - KeepInTouchView(QWidget* parent); - ~KeepInTouchView() = default; - - bool eventFilter(QObject *watched, QEvent *event); - - Q_SIGNALS: - void linkActivatedSignal(const QString& link); - - private: - bool LaunchSocialMediaUrl(SocialMediaType type); - - Ui::KeepInTouchViewWidget* m_ui = nullptr; - - const char* m_twitchUrl = "https://docs.aws.amazon.com/console/lumberyard/twitch"; - const char* m_twitterUrl = "https://docs.aws.amazon.com/console/lumberyard/twitter"; - const char* m_youtubeUrl = "https://docs.aws.amazon.com/console/lumberyard/youtube"; - const char* m_facebookUrl = "https://docs.aws.amazon.com/console/lumberyard/facebook"; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui deleted file mode 100644 index 076059f49d..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui +++ /dev/null @@ -1,423 +0,0 @@ - - - KeepInTouchViewWidget - - - - 0 - 0 - 430 - 336 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 430 - 184 - - - - - 430 - 184 - - - - - - - :/images/Resources/KeepInTouchBanner.jpg - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Keep in touch! - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 12 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Want to know the latest news at AmazonGameDev? Sign up for our newsletter and use the following links to find us! - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 0 - - - 0 - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - background: transparent; - - - - 20 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_twitch.png - - - - - - - Twitch - - - - - - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_twitter.png - - - - - - - Twitter - - - - - - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_youtube.png - - - - - - - Youtube - - - - - - - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_facebook.png - - - - - - - Facebook - - - - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - -
diff --git a/Code/Tools/News/NewsShared/Qt/NewsShared.qrc b/Code/Tools/News/NewsShared/Qt/NewsShared.qrc deleted file mode 100644 index 8d5b84494b..0000000000 --- a/Code/Tools/News/NewsShared/Qt/NewsShared.qrc +++ /dev/null @@ -1,10 +0,0 @@ - - - ../Resources/ErrorImage.jpg - ../Resources/KeepInTouchBanner.jpg - ../Resources/icon_facebook.png - ../Resources/icon_twitch.png - ../Resources/icon_twitter.png - ../Resources/icon_youtube.png - - diff --git a/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui b/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui deleted file mode 100644 index 928046a064..0000000000 --- a/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui +++ /dev/null @@ -1,260 +0,0 @@ - - - PinnedArticleViewWidget - - - - 0 - 0 - 430 - 376 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - pinned - - - - 12 - - - 16 - - - 16 - - - 16 - - - 16 - - - - - - 128 - 0 - - - - - 128 - 16777215 - - - - background-color: transparent; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 128 - 96 - - - - - 128 - 96 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - background-color: transparent; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Title: - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - sectionTitle - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Body - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp deleted file mode 100644 index c26d2357d7..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDescriptor.h" -#include "Resource.h" - -#include -#include - -using namespace News; - -ArticleDescriptor::ArticleDescriptor( - Resource& resource) - : JsonDescriptor(resource) - , m_imageId(m_json["image"].toString()) - , m_title(m_json["title"].toString()) - , m_body(m_json["body"].toString()) - , m_order(m_json["order"].toInt()) -{ - if (m_json.contains("articleStyle") == true) - { - m_articleStyle = m_json["articleStyle"].toString(); - } -} - -void ArticleDescriptor::Update() const -{ - QJsonObject json; - json["image"] = m_imageId; - json["title"] = m_title; - json["body"] = m_body; - json["order"] = m_order; - json["articleStyle"] = m_articleStyle; - QJsonDocument doc(json); - QByteArray data = doc.toJson(QJsonDocument::Compact).toStdString().data(); - m_resource.SetData(data); -} - -const QString& ArticleDescriptor::GetArticleStyle() const -{ - return m_articleStyle; -} - -void ArticleDescriptor::SetArticleStyle(const QString& style) -{ - m_articleStyle = style; -} - -const QString& ArticleDescriptor::GetImageId() const -{ - return m_imageId; -} - -void ArticleDescriptor::SetImageId(const QString& imageId) -{ - m_imageId = imageId; -} - -const QString& ArticleDescriptor::GetTitle() const -{ - return m_title; -} - -void ArticleDescriptor::SetTitle(const QString& title) -{ - m_title = title; -} - -const QString& ArticleDescriptor::GetBody() const -{ - return m_body; -} - -void ArticleDescriptor::SetBody(const QString& body) -{ - m_body = body; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h deleted file mode 100644 index c0ca459cf4..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "JsonDescriptor.h" - -#include - -namespace News -{ - class Resource; - - //! ArticleDescriptor represents Resource as an article - class ArticleDescriptor - : public JsonDescriptor - { - public: - explicit ArticleDescriptor(Resource& resource); - - //! If article was modified, call this to update resource data - void Update() const; - - const QString& GetArticleStyle() const; - - void SetArticleStyle(const QString& style); - - const QString& GetImageId() const; - - void SetImageId(const QString& imageId); - - const QString& GetTitle() const; - - void SetTitle(const QString& title); - - const QString& GetBody() const; - - void SetBody(const QString& body); - - private: - QString m_articleStyle = "default"; - QString m_imageId; - QString m_title; - QString m_body; - int m_order; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp deleted file mode 100644 index 0d21a18c05..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "Descriptor.h" - -using namespace News; - -Descriptor::Descriptor(Resource& resource) - : m_resource(resource) {} - -Descriptor::~Descriptor() {} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h deleted file mode 100644 index 3d56037543..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace News -{ - class Resource; - - //! Descriptor is a simple solution to add additional functionality to a Resource - /*! - Some descriptors can only work with certain resource types, like AerticleDescriptor - */ - class Descriptor - { - public: - explicit Descriptor(Resource& resource); - virtual ~Descriptor(); - - Resource& GetResource() const - { - return m_resource; - } - - protected: - Resource& m_resource; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp deleted file mode 100644 index 5e71c8f10b..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "JsonDescriptor.h" -#include "Resource.h" - -#include - -using namespace News; - -JsonDescriptor::JsonDescriptor(Resource& resource) - : Descriptor(resource) - , m_doc(QJsonDocument::fromJson(m_resource.GetData())) - , m_json(m_doc.object()) -{ -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h deleted file mode 100644 index 286e66c4ac..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "Descriptor.h" - -#include -#include - -namespace News -{ - //! JsonDescriptor assumes Resource is a JSON file - class JsonDescriptor - : public Descriptor - { - public: - explicit JsonDescriptor(Resource& resource); - - protected: - QJsonDocument m_doc; - QJsonObject m_json; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp deleted file mode 100644 index e70285fd31..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QtDownloadManager.h" -#include "QtDownloader.h" - -namespace News -{ - -QtDownloadManager::QtDownloadManager() - : QObject() - , m_worker(new QtDownloader) // this will start the thread which does downloads -{ - // make sure the response handlers are queued connections as the worker runs in a different thread - connect(m_worker, &QtDownloader::failed, this, &QtDownloadManager::failedReply, Qt::QueuedConnection); - connect(m_worker, &QtDownloader::successfullyFinished, this, &QtDownloadManager::successfulReply, Qt::QueuedConnection); -} - -QtDownloadManager::~QtDownloadManager() -{ - // NOTE: we don't delete the QtDownloader; it deletes itself. - // We just tell it to stop - m_worker->Finish(); -} - -void QtDownloadManager::Download(const QString& url, - std::function downloadSuccessCallback, - std::function downloadFailCallback) -{ - int downloadId = m_worker->Download(url); - m_downloads[downloadId] = { downloadSuccessCallback, downloadFailCallback }; -} - -void QtDownloadManager::Abort() -{ - m_worker->Abort(); - m_downloads.clear(); -} - -void QtDownloadManager::successfulReply(int downloadId, QByteArray data) -{ - m_downloads[downloadId].downloadSuccessCallback(data); - m_downloads.remove(downloadId); -} - -void QtDownloadManager::failedReply(int downloadId) -{ - m_downloads[downloadId].downloadFailCallback(); - m_downloads.remove(downloadId); -} - -} // namespace News - -#include "NewsShared/ResourceManagement/moc_QtDownloadManager.cpp" diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h deleted file mode 100644 index 6a7c93a51f..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include - -#include -#include -#endif - -namespace News -{ - class QtDownloader; - - //! QtDownloadManager handles multiple asynchronous downloads - class QtDownloadManager - : public QObject - { - Q_OBJECT - public: - QtDownloadManager(); - ~QtDownloadManager(); - - //! Asynchronously download a file from the input url and return it as QByteArray via the success callback - /*! - \param url - file url to download - \param downloadSuccessCallback - if download is successful pass file's data as QByteArray - \param downloadFailCallback - if download failed, pass error message - */ - void Download(const QString& url, - std::function downloadSuccessCallback, - std::function downloadFailCallback); - - //! Aborts all currently active downloads. Success/failure callbacks will not be called. - void Abort(); - - private: - void successfulReply(int downloadId, QByteArray data); - void failedReply(int downloadId); - - QtDownloader* m_worker = nullptr; - - struct DownloadResponses - { - std::function downloadSuccessCallback; - std::function downloadFailCallback; - }; - QMap m_downloads; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp deleted file mode 100644 index 0139ec5344..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QtDownloader.h" - -#include -#include -#include -#include - - -namespace News -{ - QtDownloader::QtDownloader() - : m_thread(new QThread()) - { - // make sure that everything that QObject::connects to us knows we're running in a different thread - moveToThread(m_thread); - - // handle clean up of both ourselves and of our thread. - // We manage thread clean up so that it can keep running and be cleaned up later, regardless of what - // the thing that created the QtDownloader does - connect(m_thread, &QThread::finished, m_thread, [this] { - m_thread->deleteLater(); - deleteLater(); - }); - - auto abortDownloadsHandler = [this] { - auto replies = m_downloads.keys(); - for (QNetworkReply* reply : replies) - { - reply->abort(); - } - - m_downloads.clear(); - }; - - auto queueDownloadHandler = [this](int downloadId, QString url) { - if (m_networkManager) - { - QNetworkReply* reply = m_networkManager->get(QNetworkRequest(QUrl(url))); - m_downloads.insert(reply, downloadId); - } - }; - - auto createNetworkManagerHandler = [this] { - m_networkManager = new QNetworkAccessManager; - connect(m_networkManager, &QNetworkAccessManager::finished, this, &QtDownloader::downloadFinished); - }; - - auto deleteNetworkManagerHandler = [this] { - delete m_networkManager; - m_networkManager = nullptr; - }; - - auto quitHandler = [this] { - // call quit via this callback, so that it executes in the running thread. - // QThread::quit() is actually blocking and waits until everything finishes, so - // we don't want to call it in the main thread - m_thread->quit(); - }; - - // make sure the response handlers are queued connections as the worker runs in one thread, but these triggers - // will be emitted from the main thread - connect(this, &QtDownloader::triggerAbortAll, this, abortDownloadsHandler, Qt::QueuedConnection); - connect(this, &QtDownloader::triggerDownload, this, queueDownloadHandler, Qt::QueuedConnection); - connect(this, &QtDownloader::triggerQuit, this, quitHandler, Qt::QueuedConnection); - - // create/delete the QNetworkAccessManager in our thread, to ensure that any slowdowns caused by - // having to create network connectors / load drivers are done in our non-ui thread. - // make sure that these connections are direct so that network requests can't predate the network engine itself - connect(m_thread, &QThread::started, this, createNetworkManagerHandler, Qt::DirectConnection); - connect(m_thread, &QThread::finished, this, deleteNetworkManagerHandler, Qt::DirectConnection); - - m_thread->start(); - } - - QtDownloader::~QtDownloader() - { - } - - int QtDownloader::Download(const QString& url) - { - // create a unique id for this download - int downloadId = m_lastId++; - - // trigger a download running in our worker thread - Q_EMIT triggerDownload(downloadId, url); - - return downloadId; - } - - void QtDownloader::Abort() - { - // trigger an abort in our worker thread - Q_EMIT triggerAbortAll(); - } - - void QtDownloader::Finish() - { - // trigger a quit in our worker thread - Q_EMIT triggerQuit(); - } - - void QtDownloader::downloadFinished(QNetworkReply* reply) - { - // Note: this will run in our worker thread - int downloadId = m_downloads[reply]; - - // emit the signal back to the main thread indicating that we're finished, either - // successfully or unsuccessfully - if (reply->error() == QNetworkReply::NoError) - { - Q_EMIT successfullyFinished(downloadId, reply->readAll()); - } - else - { - Q_EMIT failed(downloadId); - } - - // clean up the reply; have to do this later, according to the Qt docs - reply->deleteLater(); - - // make sure to remove our reference to this reply from our list of active downloads - m_downloads.remove(reply); - } - - #include "NewsShared/ResourceManagement/moc_QtDownloader.cpp" -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h deleted file mode 100644 index 0dcc86e951..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#endif - -class QNetworkAccessManager; -class QNetworkReply; -class QThread; - -namespace News -{ - //! QtDownloader is a wrapper around Qt's file download functions - /*! - The QtDownloader spins up another thread and does all downloads in that thread. - The public slot methods (Finish, Download and Abort) can all be called from any thread. - The response signals (successfullyFinished and failed) should be QObject::connect to with - Qt::QueuedConnection, as they will be emitted from the worker thread. - */ - class QtDownloader - : public QObject - { - Q_OBJECT - - public: - QtDownloader(); - ~QtDownloader(); - - public Q_SLOTS: - void Finish(); - - int Download(const QString& url); - void Abort(); - - Q_SIGNALS: - void successfullyFinished(int downloadId, QByteArray data); - void failed(int downloadId); - - // *********************************************** - // private - DO NOT CONNECT TO outside of the class! - // (qt signals can't be made private) - void triggerAbortAll(); - void triggerDownload(int downloadId, QString url); - void triggerQuit(); - // *********************************************** - - private: - void downloadFinished(QNetworkReply* reply); - - int m_lastId = 0; - - QMap m_downloads; - QNetworkAccessManager* m_networkManager = nullptr; - QThread* m_thread; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp b/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp deleted file mode 100644 index d40b66d6d7..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "Resource.h" - -#include - -using namespace News; - -Resource::Resource(const QJsonObject& json) - : Resource( - json["id"].toString(), - QByteArray(), - json["url"].toString(), - json["type"].toString(), - json["refCount"].toInt(), - json["version"].toInt()) {} - -Resource::Resource(const QString& id, const QString& type) - : Resource( - id, - QByteArray(), - "", - type, - 1, - 0) {} - -Resource::Resource(const QString& id, - const QByteArray& data, - [[maybe_unused]] const QString& url, - const QString& type, - int refCount, - int version) - : m_id(id) - , m_data(data) - , m_type(type) - , m_refCount(refCount) - , m_version(version) {} - -Resource::~Resource() {} - -void Resource::Write(QJsonObject& json) const -{ - json["id"] = m_id; - json["type"] = m_type; - json["refCount"] = m_refCount; - json["version"] = m_version; -} - -QString Resource::GetId() const -{ - return m_id; -} - -void Resource::SetId(const QString& id) -{ - m_id = id; -} - -QByteArray Resource::GetData() const -{ - return m_data; -} - -void Resource::SetData(QByteArray data) -{ - m_data = data; -} - -QString Resource::GetType() const -{ - return m_type; -} - -int Resource::GetRefCount() const -{ - return m_refCount; -} - -void Resource::SetRefCount(int refCount) -{ - m_refCount = refCount; -} - -int Resource::GetVersion() const -{ - return m_version; -} - -void Resource::SetVersion(int version) -{ - m_version = version; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Resource.h b/Code/Tools/News/NewsShared/ResourceManagement/Resource.h deleted file mode 100644 index 1174fea788..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Resource.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -class QJsonObject; - -namespace News -{ - class Descriptor; - - //! Resource is a central element of in-editor messages - //! It represents articles, images, and anything else that is part of news feed - class Resource - { - public: - //! resources are stored as json objects in \ref News::ResourceManifest - //! this creates resource with empty data array, that can be downloaded later - //! by calling News::ResourceManifest::Sync - explicit Resource(const QJsonObject& json); - - explicit Resource(const QString& id, - const QString& type); - - Resource(const QString& id, - const QByteArray& data, - const QString& url, - const QString& type, - int refCount, - int version); - - ~Resource(); - - //! Saves resource's description to a json file - void Write(QJsonObject& json) const; - - QString GetId() const; - - void SetId(const QString& id); - - QByteArray GetData() const; - - void SetData(QByteArray data); - - QString GetType() const; - - int GetRefCount() const; - - void SetRefCount(int refCount); - - int GetVersion() const; - - void SetVersion(int version); - - private: - QString m_id; - QByteArray m_data; - QString m_type; - int m_refCount; - int m_version; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp b/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp deleted file mode 100644 index 969c4ec8f1..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ResourceManifest.h" -#include "NewsShared/ResourceManagement/QtDownloadManager.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" - -#include -#include -#include -#include -#include - -namespace News -{ - - const QString ResourceManifest::MANIFEST_NAME = "resourceManifest"; - bool ResourceManifest::s_syncing = false; - - ResourceManifest::ResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback) - : m_downloader(new QtDownloadManager) - , m_syncSuccessCallback(syncSuccessCallback) - , m_syncFailCallback(syncFailCallback) - , m_syncUpdateCallback(syncUpdateCallback) - { - } - - ResourceManifest::~ResourceManifest() - { - // clean everything up - DeleteResources(); - - delete m_downloader; - } - - Resource* ResourceManifest::FindById(const QString& id) const - { - return FindById(id, m_resources); - } - - Resource* ResourceManifest::FindById(const QString& id, const QList& resources) - { - auto it = std::find_if( - resources.begin(), - resources.end(), - [id](Resource* resource) -> bool - { - return resource->GetId().compare(id) == 0; - }); - if (it == resources.end()) - { - return nullptr; - } - return *it; - } - - Resource* ResourceManifest::FindById(const QString& id, - const QStack& resources) - { - auto it = std::find_if( - resources.begin(), - resources.end(), - [id](Resource* resource) -> bool - { - return resource->GetId().compare(id) == 0; - }); - if (it == resources.end()) - { - return nullptr; - } - return *it; - } - - void ResourceManifest::Sync() - { - if (s_syncing) - { - FailSync(ErrorCode::AlreadySyncing); - return; - } - s_syncing = true; - m_failed = false; - - m_syncUpdateCallback("Starting sync", LogInfo); - - ReadConfig(); - - // first download the manifest json - m_syncUpdateCallback("Downloading manifest", LogInfo); - m_downloader->Download(QString(m_url).append(MANIFEST_NAME), - std::bind(&ResourceManifest::OnDownloadSuccess, this, std::placeholders::_1), - std::bind(&ResourceManifest::OnDownloadFail, this)); - } - - void ResourceManifest::Abort() - { - m_aborted = true; - m_downloader->Abort(); - } - - void ResourceManifest::Reset() - { - if (s_syncing) - { - m_syncUpdateCallback("Sync is already running", LogError); - return; - } - - m_aborted = false; - m_failed = false; - m_version = -1; - - DeleteResources(); - - m_order.clear(); - } - - QList::const_iterator ResourceManifest::begin() const - { - return m_resources.constBegin(); - } - - QList::const_iterator ResourceManifest::end() const - { - return m_resources.constEnd(); - } - - QList ResourceManifest::GetOrder() const - { - return m_order; - } - - void ResourceManifest::OnDownloadSuccess(QByteArray data) - { - QJsonDocument doc(QJsonDocument::fromJson(data)); - if (doc.isNull()) - { - FailSync(ErrorCode::FailedToParseManifest); - return; - } - - ErrorCode error = Read(doc.object()); - if (error != ErrorCode::None) - { - FailSync(error); - return; - } - - // check how many resources to sync - PrepareForSync(); - // if there is anything to sync, do that - if (m_syncLeft > 0) - { - m_syncUpdateCallback("Syncing resources", LogInfo); - SyncResources(); - } - // otherwise just finish sync - else - { - m_syncUpdateCallback("No new resources to sync", LogInfo); - FinishSync(); - } - } - - void ResourceManifest::OnDownloadFail() - { - FailSync(ErrorCode::ManifestDownloadFail); - } - - ErrorCode ResourceManifest::Read(const QJsonObject& json) - { - m_version = json["version"].toInt(); - QJsonArray resourceArray = json["resources"].toArray(); - // initially mark ALL existing resource for deletion - QList toDelete = m_resources; - - for (auto resourceDoc : resourceArray) - { - auto pNewResource = new Resource(resourceDoc.toObject()); - // find local resource with the same id as new resource - auto pOldResource = FindById(pNewResource->GetId(), m_resources); - // if resource with the same id already exists then check its version - if (pOldResource) - { - // local resource is outdated, keep it in delete list, and download new one instead - if (pNewResource->GetVersion() > pOldResource->GetVersion()) - { - m_toDownload.push(pNewResource); - } - // local resource is newer or same version, keep it (remove from toDelete list) - // and don't need to download new one - else - { - delete pNewResource; - toDelete.removeAll(pOldResource); - } - } - // resource with same id not found - else - { - m_toDownload.push(pNewResource); - } - } - - // delete everything that's not in s3 - for (auto pResource : toDelete) - { - RemoveResource(pResource); - delete pResource; - } - - // parse order of articles - m_order.clear(); - QJsonArray orderArray = json["order"].toArray(); - for (auto idObject : orderArray) - { - m_order.append(idObject.toString()); - } - return ErrorCode::None; - } - - void ResourceManifest::PrepareForSync() - { - if (m_aborted) - { - m_syncLeft = 0; - } - - m_syncLeft = m_toDownload.count(); - } - - void ResourceManifest::SyncResources() - { - DownloadResources(); - } - - void ResourceManifest::DownloadResources() - { - while (m_toDownload.count() > 0) - { - m_syncUpdateCallback( - QString("Downloading: %1 resources left").arg(m_toDownload.count()), - LogInfo); - - auto pResource = m_toDownload.pop(); - - m_downloader->Download(QString(m_url).append(pResource->GetId()), - //download success - [&, pResource](QByteArray data) - { - pResource->SetData(data); - AppendResource(pResource); - UpdateSync(); - }, - //download fail - [&, pResource]() - { - m_failed = true; - delete pResource; - m_syncUpdateCallback("Failed to download resource", LogError); - UpdateSync(); - }); - } - } - - void ResourceManifest::ReadConfig() - { - QFile file(QCoreApplication::applicationDirPath() + "/newsConfig.txt"); - if (file.exists()) - { - if (file.open(QIODevice::ReadOnly)) - { - QTextStream in(&file); - m_url = in.readAll().trimmed(); - file.close(); - } - } - } - - void ResourceManifest::DeleteResources() - { - for (auto pResource : m_toDownload) - { - delete pResource; - } - m_toDownload.clear(); - - for (auto pResource : m_resources) - { - delete pResource; - } - m_resources.clear(); - } - - void ResourceManifest::UpdateSync() - { - m_syncLeft--; - if (m_syncLeft == 0) - { - if (!m_failed) - { - FinishSync(); - } - else - { - FailSync(ErrorCode::FailedToSync); - } - } - } - - void ResourceManifest::FinishSync() - { - if (!m_failed) - { - m_syncSuccessCallback(); - } - else - { - m_syncFailCallback(m_errorCode); - } - s_syncing = false; - } - - void ResourceManifest::FailSync(ErrorCode error) - { - m_failed = true; - m_errorCode = error; - FinishSync(); - } - - void ResourceManifest::AppendResource(Resource* pResource) - { - m_resources.append(pResource); - } - - void ResourceManifest::RemoveResource(Resource* pResource) - { - m_resources.removeAll(pResource); - } - -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h b/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h deleted file mode 100644 index 3a0f31de8f..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -#include - -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" - -class QJsonObject; - -namespace News -{ - class ArticleDescriptor; - class UidGenerator; - class S3Connector; - class QtDownloadManager; - class Descriptor; - class DownloadDescriptor; - class Resource; - - //! ResourceManifest manages resources. - /*! - Manifest contains information on resources, it handles syncing resources with s3 - */ - class ResourceManifest - { - public: - //! ResourceManifest ctor - /*! - \param syncSuccessCallback - called once when everything is synced - \param syncFailCallback - called once when sync failed - \param syncUpdateCallback - called multiple times to update information on sync process - */ - explicit ResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback); - virtual ~ResourceManifest(); - - //! Find a resource that matches id - /*! - \retval Resource * - a pointer to a Resource with matching id, if none found return nullptr - */ - Resource* FindById(const QString& id) const; - static Resource* FindById(const QString& id, const QList& resources); - static Resource* FindById(const QString& id, const QStack& resources); - - //! Sync resources with s3 - /* - 1) First download resource manifest file - 2) Parse manifest - 3) Determine which resources need to be downloaded, updated, or deleted - 4) Download missing resources or resource that are out of date - 5) Call m_syncSuccessCallback - */ - virtual void Sync(); - - //! Gracegully stop sync process - /*! - Aborting works differently depending at what point during sync porocess it is called - If called before resources started to download, then skip download altogether - Otherwise gracefully abort all downloads and call m_syncFailCallback - */ - void Abort(); - - //! Called when switching endpoints to reset resource manifest to a clean state - virtual void Reset(); - - QList::const_iterator begin() const; - QList::const_iterator end() const; - - //! Get order of article resources, so they can be displayed properly in ArticleViewContainer - QList GetOrder() const; - - protected: - //! The root location of cloudfront resources - QString m_url = "https://lumberyard-data.amazon.com/"; - //! Name of resourceManifest file that links all other resources - static const QString MANIFEST_NAME; - //! Identifies whether syncing is in progress - static bool s_syncing; - //! Manifest Version - int m_version = -1; - //! Number of resources left to sync - int m_syncLeft = 0; - //! Identifies whether sync process was aborted - bool m_aborted = false; - //! Indentifies whether sync process has failed - bool m_failed = false; - ErrorCode m_errorCode = ErrorCode::None; - - QtDownloadManager* m_downloader = nullptr; - - QList m_resources; - QList m_order; - QStack m_toDownload; - - std::function m_syncSuccessCallback; - std::function m_syncFailCallback; - std::function m_syncUpdateCallback; - - //! Parse resource manifest json, and figure out which resources need to be downloaded - virtual ErrorCode Read(const QJsonObject& json); - - //! Executed before sync to figure out how many resources need to be synced - virtual void PrepareForSync(); - //! Actual sync function - virtual void SyncResources(); - //! Check whether everything is synced, if so call ResourceManifest::FinishSync - void UpdateSync(); - //! Notify that everything is synced - virtual void FinishSync(); - void FailSync(ErrorCode error); - - virtual void AppendResource(Resource* pResource); - virtual void RemoveResource(Resource* pResource); - - virtual void OnDownloadSuccess(QByteArray data); - virtual void OnDownloadFail(); - virtual void DownloadResources(); - - private: - void ReadConfig(); - void DeleteResources(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg b/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg deleted file mode 100644 index 216fe14bd5..0000000000 --- a/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a7430d63820b3b00e03b4a8ec73b5e8e3946659031e3aeeb355b632acca4122 -size 8857 diff --git a/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg b/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg deleted file mode 100644 index b47040b717..0000000000 --- a/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:09c1733f116c11b56c54f7c3b6b4462884116db06605ca3cdfa23c45a3695385 -size 68024 diff --git a/Code/Tools/News/NewsShared/Resources/icon_facebook.png b/Code/Tools/News/NewsShared/Resources/icon_facebook.png deleted file mode 100644 index 0fb823969b..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_facebook.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f8b5493c81354b6757a21bea6baedd5665b8cb9ca19a6ff4fbd40afef534f35f -size 1257 diff --git a/Code/Tools/News/NewsShared/Resources/icon_twitch.png b/Code/Tools/News/NewsShared/Resources/icon_twitch.png deleted file mode 100644 index 50d7436b0d..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_twitch.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2882aad73e2ecf310934ec3eacd0c1fa0a6ff012a4c3c9cf4ca96a72cef2fb8c -size 514 diff --git a/Code/Tools/News/NewsShared/Resources/icon_twitter.png b/Code/Tools/News/NewsShared/Resources/icon_twitter.png deleted file mode 100644 index d1cf7eb3dd..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_twitter.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:046e14f1d90f77bb6ea0fe700bb10049748b46bb84c8ac3620642d4bca9df533 -size 954 diff --git a/Code/Tools/News/NewsShared/Resources/icon_youtube.png b/Code/Tools/News/NewsShared/Resources/icon_youtube.png deleted file mode 100644 index d3e7869387..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_youtube.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3abaf8b178763441ac6812ae518c2f8cbea9b228aa1f84052a65836b33dc980c -size 976 diff --git a/Code/Tools/News/news_shared_files.cmake b/Code/Tools/News/news_shared_files.cmake deleted file mode 100644 index 2f20029068..0000000000 --- a/Code/Tools/News/news_shared_files.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - NewsShared/LogType.h - NewsShared/ErrorCodes.h - NewsShared/Qt/ArticleErrorView.cpp - NewsShared/Qt/ArticleErrorView.h - NewsShared/Qt/ArticleErrorView.ui - NewsShared/Qt/ArticleView.cpp - NewsShared/Qt/ArticleView.h - NewsShared/Qt/ArticleView.ui - NewsShared/Qt/PinnedArticleView.ui - NewsShared/Qt/ArticleViewContainer.cpp - NewsShared/Qt/ArticleViewContainer.h - NewsShared/Qt/ArticleViewContainer.ui - NewsShared/Qt/KeepInTouchView.cpp - NewsShared/Qt/KeepInTouchView.h - NewsShared/Qt/KeepInTouchView.ui - NewsShared/Qt/NewsShared.qrc - NewsShared/ResourceManagement/ArticleDescriptor.cpp - NewsShared/ResourceManagement/ArticleDescriptor.h - NewsShared/ResourceManagement/Descriptor.cpp - NewsShared/ResourceManagement/Descriptor.h - NewsShared/ResourceManagement/JsonDescriptor.cpp - NewsShared/ResourceManagement/JsonDescriptor.h - NewsShared/ResourceManagement/QtDownloader.cpp - NewsShared/ResourceManagement/QtDownloader.h - NewsShared/ResourceManagement/QtDownloadManager.cpp - NewsShared/ResourceManagement/QtDownloadManager.h - NewsShared/ResourceManagement/Resource.cpp - NewsShared/ResourceManagement/Resource.h - NewsShared/ResourceManagement/ResourceManifest.cpp - NewsShared/ResourceManagement/ResourceManifest.h - NewsShared/Resources/ErrorImage.jpg - NewsShared/Resources/KeepInTouchBanner.jpg - NewsShared/Resources/icon_facebook.png - NewsShared/Resources/icon_twitch.png - NewsShared/Resources/icon_twitter.png - NewsShared/Resources/icon_youtube.png -) diff --git a/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg b/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg new file mode 100644 index 0000000000..9ab30acd65 --- /dev/null +++ b/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc index cfe4b37fbc..2e93e9eca9 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc @@ -34,5 +34,6 @@ Warning.svg Backgrounds/DefaultBackground.jpg Backgrounds/FtueBackground.jpg + FeatureTagClose.svg diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index d6a2476e83..74acc1c7ef 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -435,8 +435,6 @@ QProgressBar { border: none; background-color: transparent; padding: 0px; - min-height: 14px; - font-size: 2px; } QProgressBar::chunk { @@ -478,6 +476,13 @@ QProgressBar::chunk { background-color: #333333; } +/************** Filter tag widget **************/ + +#FilterTagWidgetTextLabel { + color: #94D2FF; + font-size: 10px; +} + /************** Gem Catalog (Inspector) **************/ #GemCatalogInspector { diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp new file mode 100644 index 0000000000..c7925a2d6e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + FilterTagWidget::FilterTagWidget(const QString& text, QWidget* parent) + : QFrame(parent) + { + setFrameShape(QFrame::NoFrame); + + auto* layout = new QHBoxLayout(); + layout->setContentsMargins(6, 5, 4, 4); + layout->setSpacing(2); + setLayout(layout); + + setStyleSheet("background-color: #555555;"); + + m_textLabel = new QLabel(); + m_textLabel->setObjectName("FilterTagWidgetTextLabel"); + m_textLabel->setText(text); + layout->addWidget(m_textLabel); + + m_closeButton = new QPushButton(); + m_closeButton->setFlat(true); + m_closeButton->setIcon(QIcon(":/FeatureTagClose.svg")); + m_closeButton->setIconSize(QSize(12, 12)); + m_closeButton->setStyleSheet("QPushButton { background-color: transparent; border: 0px }"); + layout->addWidget(m_closeButton); + connect(m_closeButton, &QPushButton::clicked, this, [=]{ emit RemoveClicked(); }); + } + + QString FilterTagWidget::text() const + { + return m_textLabel->text(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + FilterTagWidgetContainer::FilterTagWidgetContainer(QWidget* parent) + : QWidget(parent) + { + m_layout = new QHBoxLayout(); + m_layout->setMargin(0); + m_layout->setSpacing(0); + setLayout(m_layout); + } + + void FilterTagWidgetContainer::Reinit(const QVector& tags) + { + if (m_widget) + { + // Hide the old widget and request deletion. + m_widget->hide(); + m_widget->deleteLater(); + } + + m_widget = new QWidget(this); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setAlignment(Qt::AlignLeft); + hLayout->setMargin(0); + hLayout->setSpacing(8); + + for(const QString& tag : tags) + { + FilterTagWidget* tagWidget = new FilterTagWidget(tag); + + // Add the tag widget to the current row. + hLayout->addWidget(tagWidget); + + // Connect the clicked event of the close button of the tag widget to the remove tag function in the container. + connect(tagWidget, &FilterTagWidget::RemoveClicked, this, [this, tagWidget]{ emit TagRemoved(tagWidget->text()); }); + } + + QWidget* spacerWidget = new QWidget(); + spacerWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + hLayout->addWidget(spacerWidget); + + m_widget->setLayout(hLayout); + m_layout->addWidget(m_widget); + + setFixedHeight(30); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h new file mode 100644 index 0000000000..0994618d4e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QHBoxLayout) +QT_FORWARD_DECLARE_CLASS(QLabel) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QWidget) + +namespace O3DE::ProjectManager +{ + class FilterTagWidget + : public QFrame + { + Q_OBJECT + + public: + FilterTagWidget(const QString& text, QWidget* parent = nullptr); + QString text() const; + + signals: + void RemoveClicked(); + + private: + QLabel* m_textLabel = nullptr; + QPushButton* m_closeButton = nullptr; + }; + + // Horizontally expanding filter tag container widget + class FilterTagWidgetContainer + : public QWidget + { + Q_OBJECT + + public: + FilterTagWidgetContainer(QWidget* parent = nullptr); + void Reinit(const QVector& tags); + + signals: + void TagRemoved(QString tagName); + + private: + QWidget* m_widget = nullptr; + QHBoxLayout* m_layout = nullptr; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp index 753371ba52..268e793ee8 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -485,6 +486,7 @@ namespace O3DE::ProjectManager const QString& feature = elementNames[i]; QAbstractButton* button = buttons[i]; + // Adjust the proxy model and enable or disable the clicked feature used for filtering. connect(button, &QAbstractButton::toggled, this, [=](bool checked) { QSet features = m_filterProxyModel->GetFeatures(); @@ -498,6 +500,15 @@ namespace O3DE::ProjectManager } m_filterProxyModel->SetFeatures(features); }); + + // Sync the UI state with the proxy model filtering. + connect(m_filterProxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=] + { + const QSet& filteredFeatureTags = m_filterProxyModel->GetFeatures(); + const bool isChecked = filteredFeatureTags.contains(button->text()); + QSignalBlocker signalsBlocker(button); + button->setChecked(isChecked); + }); } } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp index b9dc3e9fcc..f5bedb79eb 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp @@ -102,9 +102,11 @@ namespace O3DE::ProjectManager // In case there are feature tags displayed at the bottom, decrease the size of the summary text field. const QStringList featureTags = GemModel::GetFeatures(modelIndex); - const int summaryHeight = contentRect.height() - (!featureTags.empty() * 30); + const int featureTagAreaHeight = 30; + const int summaryHeight = contentRect.height() - (!featureTags.empty() * featureTagAreaHeight); - const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 3, + const int additionalSummarySpacing = s_itemMargins.right() * 3; + const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - additionalSummarySpacing, summaryHeight); const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp index 5e2f93c2fc..3d6fd1947c 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp @@ -7,10 +7,13 @@ #include #include -#include +#include +#include +#include #include -#include #include +#include +#include namespace O3DE::ProjectManager { @@ -23,11 +26,34 @@ namespace O3DE::ProjectManager setStyleSheet("background-color: #333333;"); - vLayout->addSpacing(20); + vLayout->addSpacing(13); // Top section QHBoxLayout* topLayout = new QHBoxLayout(); + topLayout->addSpacing(16); topLayout->setMargin(0); + + auto* tagWidget = new FilterTagWidgetContainer(); + + // Adjust the proxy model and disable the given feature used for filtering. + connect(tagWidget, &FilterTagWidgetContainer::TagRemoved, this, [=](QString tagName) + { + QSet filteredFeatureTags = proxyModel->GetFeatures(); + filteredFeatureTags.remove(tagName); + proxyModel->SetFeatures(filteredFeatureTags); + }); + + // Reinitialize the tag widget in case the filter in the proxy model got invalided. + connect(proxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=] + { + const QSet& tagSet = proxyModel->GetFeatures(); + QVector sortedTags(tagSet.begin(), tagSet.end()); + std::sort(sortedTags.begin(), sortedTags.end()); + tagWidget->Reinit(sortedTags); + }); + + topLayout->addWidget(tagWidget); + topLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); QLabel* showCountLabel = new QLabel(); @@ -43,7 +69,7 @@ namespace O3DE::ProjectManager vLayout->addLayout(topLayout); - vLayout->addSpacing(20); + vLayout->addSpacing(13); // Separating line QFrame* hLine = new QFrame(); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h index a9b3b3aa36..fcad58a321 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h @@ -8,9 +8,8 @@ #pragma once #if !defined(Q_MOC_RUN) +#include #include -#include -#include #include #endif diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index c0c96d8281..508b7256d1 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -117,7 +118,7 @@ namespace O3DE::ProjectManager for (int index = 0; index < m_templates.size(); ++index) { ProjectTemplateInfo projectTemplate = m_templates.at(index); - QString projectPreviewPath = projectTemplate.m_path + "/Template/preview.png"; + QString projectPreviewPath = QDir(projectTemplate.m_path).filePath(ProjectPreviewImagePath); QFileInfo doesPreviewExist(projectPreviewPath); if (!doesPreviewExist.exists() || !doesPreviewExist.isFile()) { diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h index f74233db51..79ad04c43a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h @@ -12,6 +12,7 @@ namespace O3DE::ProjectManager { inline constexpr static int ProjectPreviewImageWidth = 210; inline constexpr static int ProjectPreviewImageHeight = 280; + inline constexpr static int ProjectTemplateImageWidth = 92; static const QString ProjectBuildPathPostfix = "build/windows_vs2019"; static const QString ProjectBuildPathCmakeFiles = "CMakeFiles"; diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp index f7a90f5e0c..83e7546670 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include #include +#include namespace O3DE::ProjectManager { @@ -55,7 +57,42 @@ namespace O3DE::ProjectManager return false; } - static bool CopyDirectory(const QString& origPath, const QString& newPath) + typedef AZStd::function StatusFunction; + static void RecursiveGetAllFiles(const QDir& directory, QStringList& outFileList, qint64& outTotalSizeInBytes, StatusFunction statusCallback) + { + const QStringList entries = directory.entryList(QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot); + for (const QString& entryPath : entries) + { + const QString filePath = QDir::toNativeSeparators(QString("%1/%2").arg(directory.path()).arg(entryPath)); + QFileInfo fileInfo(filePath); + + if (fileInfo.isDir()) + { + QDir subDirectory(filePath); + RecursiveGetAllFiles(subDirectory, outFileList, outTotalSizeInBytes, statusCallback); + } + else + { + outFileList.push_back(filePath); + outTotalSizeInBytes += fileInfo.size(); + + const int updateStatusEvery = 64; + if (outFileList.size() % updateStatusEvery == 0) + { + statusCallback(outFileList.size(), outTotalSizeInBytes); + } + } + } + } + + static bool CopyDirectory(QProgressDialog* progressDialog, + const QString& origPath, + const QString& newPath, + QStringList& filesToCopy, + int& outNumCopiedFiles, + qint64 totalSizeToCopy, + qint64& outCopiedFileSize, + bool& showIgnoreFileDialog) { QDir original(origPath); if (!original.exists()) @@ -65,19 +102,91 @@ namespace O3DE::ProjectManager for (QString directory : original.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + if (progressDialog->wasCanceled()) + { + return false; + } + QString newDirectoryPath = newPath + QDir::separator() + directory; original.mkpath(newDirectoryPath); - if (!CopyDirectory(origPath + QDir::separator() + directory, newDirectoryPath)) + if (!CopyDirectory(progressDialog, origPath + QDir::separator() + directory, + newDirectoryPath, filesToCopy, outNumCopiedFiles, totalSizeToCopy, outCopiedFileSize, showIgnoreFileDialog)) { return false; } } + QLocale locale; + const float progressDialogRangeHalf = qFabs(progressDialog->maximum() - progressDialog->minimum()) * 0.5f; for (QString file : original.entryList(QDir::Files)) { - if (!QFile::copy(origPath + QDir::separator() + file, newPath + QDir::separator() + file)) + if (progressDialog->wasCanceled()) + { return false; + } + + // Progress window update + { + // Weight in the number of already copied files as well as the copied bytes to get a better progress indication + // for cases combining many small files and some really large files. + const float normalizedNumFiles = static_cast(outNumCopiedFiles) / filesToCopy.count(); + const float normalizedFileSize = static_cast(outCopiedFileSize) / totalSizeToCopy; + const int progress = normalizedNumFiles * progressDialogRangeHalf + normalizedFileSize * progressDialogRangeHalf; + progressDialog->setValue(progress); + + const QString copiedFileSizeString = locale.formattedDataSize(outCopiedFileSize); + const QString totalFileSizeString = locale.formattedDataSize(totalSizeToCopy); + progressDialog->setLabelText(QString("Coping file %1 of %2 (%3 of %4) ...").arg(QString::number(outNumCopiedFiles), + QString::number(filesToCopy.count()), + copiedFileSizeString, + totalFileSizeString)); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + } + + const QString toBeCopiedFilePath = origPath + QDir::separator() + file; + const QString copyToFilePath = newPath + QDir::separator() + file; + if (!QFile::copy(toBeCopiedFilePath, copyToFilePath)) + { + // Let the user decide to ignore files that failed to copy or cancel the whole operation. + if (showIgnoreFileDialog) + { + QMessageBox ignoreFileMessageBox; + const QString text = QString("Cannot copy %1.

" + "Source: %2
" + "Destination: %3

" + "Press Yes to ignore the file, YesToAll to ignore all upcoming non-copyable files or " + "Cancel to abort duplicating the project.").arg(file, toBeCopiedFilePath, copyToFilePath); + + ignoreFileMessageBox.setModal(true); + ignoreFileMessageBox.setWindowTitle("Cannot copy file"); + ignoreFileMessageBox.setText(text); + ignoreFileMessageBox.setIcon(QMessageBox::Question); + ignoreFileMessageBox.setStandardButtons(QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::Cancel); + + int ignoreFile = ignoreFileMessageBox.exec(); + if (ignoreFile == QMessageBox::YesToAll) + { + showIgnoreFileDialog = false; + continue; + } + else if (ignoreFile == QMessageBox::Yes) + { + continue; + } + else + { + return false; + } + } + } + else + { + outNumCopiedFiles++; + + QFileInfo fileInfo(toBeCopiedFilePath); + outCopiedFileSize += fileInfo.size(); + } } return true; @@ -119,16 +228,13 @@ namespace O3DE::ProjectManager return false; } - QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - copyResult = CopyProject(origPath, newPath); - QGuiApplication::restoreOverrideCursor(); - + copyResult = CopyProject(origPath, newPath, parent); } return copyResult; } - bool CopyProject(const QString& origPath, const QString& newPath) + bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent) { // Disallow copying from or into subdirectory if (IsDirectoryDescedent(origPath, newPath) || IsDirectoryDescedent(newPath, origPath)) @@ -136,19 +242,54 @@ namespace O3DE::ProjectManager return false; } - if (!CopyDirectory(origPath, newPath)) + QStringList filesToCopy; + qint64 totalSizeInBytes = 0; + + QProgressDialog* progressDialog = new QProgressDialog(parent); + progressDialog->setAutoClose(true); + progressDialog->setValue(0); + progressDialog->setRange(0, 1000); + progressDialog->setModal(true); + progressDialog->setWindowTitle(QObject::tr("Copying project ...")); + progressDialog->show(); + + QLocale locale; + RecursiveGetAllFiles(origPath, filesToCopy, totalSizeInBytes, [=](int fileCount, int sizeInBytes) + { + // Create a human-readable version of the file size. + const QString fileSizeString = locale.formattedDataSize(sizeInBytes); + + progressDialog->setLabelText(QString("%1 ... %2 %3, %4 %5.") + .arg(QObject::tr("Indexing files")) + .arg(QString::number(fileCount)) + .arg(QObject::tr("files found")) + .arg(fileSizeString) + .arg(QObject::tr("to copy"))); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + }); + + int numFilesCopied = 0; + qint64 copiedFileSize = 0; + + // Phase 1: Copy files + bool showIgnoreFileDialog = true; + bool success = CopyDirectory(progressDialog, origPath, newPath, filesToCopy, numFilesCopied, totalSizeInBytes, copiedFileSize, showIgnoreFileDialog); + if (success) { - // Cleanup whatever mess was made - DeleteProjectFiles(newPath, true); - return false; + // Phase 2: Register project + success = RegisterProject(newPath); } - if (!RegisterProject(newPath)) + if (!success) { + progressDialog->setLabelText(QObject::tr("Duplicating project failed/cancelled, removing already copied files ...")); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + DeleteProjectFiles(newPath, true); } - return true; + progressDialog->deleteLater(); + return success; } bool DeleteProjectFiles(const QString& path, bool force) @@ -184,7 +325,7 @@ namespace O3DE::ProjectManager if (!newDirectory.rename(origPath, newPath)) { // Likely failed because trying to move to another partition, try copying - if (!CopyProject(origPath, newPath)) + if (!CopyProject(origPath, newPath, parent)) { return false; } @@ -272,7 +413,6 @@ namespace O3DE::ProjectManager bool IsVS2019Installed() { static bool vs2019Installed = IsVS2019Installed_internal(); - return vs2019Installed; } diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.h b/Code/Tools/ProjectManager/Source/ProjectUtils.h index 786ff34b88..2829a45180 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.h +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.h @@ -17,7 +17,7 @@ namespace O3DE::ProjectManager bool RegisterProject(const QString& path); bool UnregisterProject(const QString& path); bool CopyProjectDialog(const QString& origPath, QWidget* parent = nullptr); - bool CopyProject(const QString& origPath, const QString& newPath); + bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent); bool DeleteProjectFiles(const QString& path, bool force = false); bool MoveProject(QString origPath, QString newPath, QWidget* parent = nullptr, bool ignoreRegister = false); diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 167cf6d10e..f8e90b0a59 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -394,13 +394,20 @@ namespace O3DE::ProjectManager if (pybind11::isinstance(o3deData)) { engineInfo.m_path = Py_To_String(enginePath); - engineInfo.m_defaultGemsFolder = Py_To_String(o3deData["default_gems_folder"]); - engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]); - engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]); - engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]); + auto defaultGemsFolder = m_manifest.attr("get_o3de_gems_folder")(); + engineInfo.m_defaultGemsFolder = Py_To_String_Optional(o3deData, "default_gems_folder", Py_To_String(defaultGemsFolder)); + + auto defaultProjectsFolder = m_manifest.attr("get_o3de_projects_folder")(); + engineInfo.m_defaultProjectsFolder = Py_To_String_Optional(o3deData, "default_projects_folder", Py_To_String(defaultProjectsFolder)); + + auto defaultRestrictedFolder = m_manifest.attr("get_o3de_restricted_folder")(); + engineInfo.m_defaultRestrictedFolder = Py_To_String_Optional(o3deData, "default_restricted_folder", Py_To_String(defaultRestrictedFolder)); + + auto defaultTemplatesFolder = m_manifest.attr("get_o3de_templates_folder")(); + engineInfo.m_defaultTemplatesFolder = Py_To_String_Optional(o3deData, "default_templates_folder", Py_To_String(defaultTemplatesFolder)); auto defaultThirdPartyFolder = m_manifest.attr("get_o3de_third_party_folder")(); - engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); + engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData, "default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); } auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath); diff --git a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp index d20b91ac8e..638b821e5d 100644 --- a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp +++ b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -16,7 +17,6 @@ namespace O3DE::ProjectManager { - TemplateButton::TemplateButton(const QString& imagePath, const QString& labelText, QWidget* parent) : QPushButton(parent) { @@ -31,8 +31,8 @@ namespace O3DE::ProjectManager QLabel* image = new QLabel(this); image->setObjectName("templateImage"); - image->setPixmap( - QPixmap(imagePath).scaled(QSize(s_templateImageWidth,s_templateImageHeight) , Qt::KeepAspectRatio, Qt::SmoothTransformation)); + image->setPixmap(QPixmap(imagePath).scaled( + QSize(ProjectTemplateImageWidth, ProjectTemplateImageWidth), Qt::KeepAspectRatio, Qt::SmoothTransformation)); vLayout->addWidget(image); QLabel* label = new QLabel(labelText, this); diff --git a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h index 2b2b3474c2..0607b8fbfe 100644 --- a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h +++ b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h @@ -24,9 +24,5 @@ namespace O3DE::ProjectManager protected slots: void onToggled(); - - private: - inline constexpr static int s_templateImageWidth = 92; - inline constexpr static int s_templateImageHeight = 122; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index a5632f082c..07c649624e 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -71,6 +71,8 @@ set(FILES Source/GemCatalog/GemCatalogHeaderWidget.cpp Source/GemCatalog/GemCatalogScreen.h Source/GemCatalog/GemCatalogScreen.cpp + Source/GemCatalog/GemFilterTagWidget.h + Source/GemCatalog/GemFilterTagWidget.cpp Source/GemCatalog/GemFilterWidget.h Source/GemCatalog/GemFilterWidget.cpp Source/GemCatalog/GemInfo.h diff --git a/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp b/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp index c8c16cd26f..a6ba5812a1 100644 --- a/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp +++ b/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -163,7 +164,11 @@ namespace AWSClientAuth void AWSClientAuthSystemComponent::OnSDKInitialized() { - Aws::Client::ClientConfiguration clientConfiguration; + AWSCore::AwsApiJobConfig* defaultConfig; + AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig); + Aws::Client::ClientConfiguration clientConfiguration = + defaultConfig ? defaultConfig->GetClientConfiguration() : Aws::Client::ClientConfiguration(); + AZStd::string region; AWSCore::AWSResourceMappingRequestBus::BroadcastResult(region, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion); diff --git a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h index cf6364fa00..dc9a84bc0a 100644 --- a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h +++ b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h @@ -113,6 +113,27 @@ namespace AWSClientAuthUnitTest MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName)); }; + class AWSCoreRequestBusMock + : public AWSCore::AWSCoreRequestBus::Handler + { + public: + AWSCoreRequestBusMock() + { + AWSCore::AWSCoreRequestBus::Handler::BusConnect(); + + ON_CALL(*this, GetDefaultJobContext).WillByDefault(testing::Return(nullptr)); + ON_CALL(*this, GetDefaultConfig).WillByDefault(testing::Return(nullptr)); + } + + ~AWSCoreRequestBusMock() + { + AWSCore::AWSCoreRequestBus::Handler::BusDisconnect(); + } + + MOCK_METHOD0(GetDefaultJobContext, AZ::JobContext*()); + MOCK_METHOD0(GetDefaultConfig, AWSCore::AwsApiJobConfig*()); + }; + class HttpRequestorRequestBusMock : public HttpRequestor::HttpRequestorRequestBus::Handler { diff --git a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp index 7a5ddc1f61..1b4fe3b3a1 100644 --- a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp +++ b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp @@ -161,6 +161,7 @@ public: testing::NiceMock *m_awsClientAuthSystemsComponent; testing::NiceMock *m_awsCoreSystemsComponent; testing::NiceMock m_awsResourceMappingRequestBusMock; + testing::NiceMock m_awsCoreRequestBusMock; AZ::Entity* m_entity = nullptr; }; @@ -176,6 +177,7 @@ TEST_F(AWSClientAuthSystemComponentTest, ActivateDeactivate_Success) EXPECT_CALL(*m_awsCoreSystemsComponent, Init()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsClientAuthSystemsComponent, Init()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsCoreSystemsComponent, Activate()).Times(1).InSequence(s1); + EXPECT_CALL(m_awsCoreRequestBusMock, GetDefaultConfig()).Times(1).InSequence(s1); EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsClientAuthSystemsComponent, Activate()).Times(1).InSequence(s1); diff --git a/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem b/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem new file mode 100644 index 0000000000..cb8f3ada5c --- /dev/null +++ b/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem @@ -0,0 +1,4043 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Wed Jan 18 04:12:05 2017 GMT +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.27. +## SHA256: dffa79e6aa993f558e82884abf7bb54bf440ab66ee91d82a27a627f6f2a4ace4 +## + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 +MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM +MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF +NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe +AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC +b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn +7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN +cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp +WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 +haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY +MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 +MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn +jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ +MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H +VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl +vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl +OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 +1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq +nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy +x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================ +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2007 +================================================= +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +PSCProcert +========== +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk +ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ +MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz +dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl +cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw +IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw +MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w +DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD +ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp +Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC +wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA +3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh +RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO +EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 +0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU +td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw +Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp +r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ +AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz +Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId +xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp +ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH +EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h +Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k +ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG +9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG +MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG +LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 +ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy +YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o +dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq +T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN +g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q +uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 +n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn +FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo +5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq +3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 +poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y +eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +China Internet Network Information Center EV Certificates Root +============================================================== +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D +aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg +Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG +A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM +PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl +cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y +jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV +98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H +klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 +KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC +7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD +glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 +0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM +7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws +ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 +5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= +-----END CERTIFICATE----- + +Swisscom Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 +MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM +LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo +ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ +wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH +Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a +SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS +NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab +mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY +Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 +qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu +MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO +v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ +82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz +o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs +a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx +OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW +mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o ++sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC +rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX +5OfNeOI5wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- + +Swisscom Root EV CA 2 +===================== +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE +BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl +cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN +MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT +HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg +Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz +o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy +Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti +GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li +qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH +Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG +alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa +m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox +bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi +xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB +bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL +j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU +wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 +XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH +59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ +23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq +J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA +HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi +uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW +l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- + +CA Disig Root R1 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy +3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 +u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 +m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk +CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa +YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 +vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL +LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX +ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is +XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ +04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B +LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM +CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb +VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 +YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS +ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix +lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N +UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ +a7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +WoSign +====== +-----BEGIN CERTIFICATE----- +MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ +BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO +CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX +2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5 +KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR ++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez +EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk +lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2 +8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY +yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C +AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R +8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 +LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq +T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj +y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC +2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes +5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/ +EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh +mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx +kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi +kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w== +-----END CERTIFICATE----- + +WoSign China +============ +-----BEGIN CERTIFICATE----- +MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv +geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD +VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k +8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5 +uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85 +dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5 +Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy +b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc +76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m ++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6 +yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX +GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA +A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 +yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY +r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115 +j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A +kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97 +qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y +jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB +ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv +T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO +kI26oQ== +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl +OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV +MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF +JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G3 +================================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y +olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t +x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy +EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K +Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur +mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 +1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp +07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo +FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE +41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu +yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq +KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 +v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA +8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b +8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r +mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq +1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI +JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV +tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 +==================================================== +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg +RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw +ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w +SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE +n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp +ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 +jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m +ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP +9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV +4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH +HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo +BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl +lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 +B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 +==================================================== +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5 +MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL +BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf +aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm +aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a +2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED +wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb +HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV ++DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT +9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R +fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW +hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1 +O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw== +-----END CERTIFICATE----- + +Certinomis - Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg +LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx +EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD +ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos +P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo +d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap +z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 +8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x +RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE +6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t +FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV +PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH +i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj +YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I +6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV +WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw +Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX +lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ +y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 +Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng +DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi +I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM +cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr +hkIGuUE= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +Certification Authority of WoSign G2 +==================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx +CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai +XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du +W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9 +5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK +v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI +hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY +P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3 +TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu ++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+ +7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +CA WoSign ECC Root +================== +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD +TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v +dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU +t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw +QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R +MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 +Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu +a/GRspBl9JrmkO5K +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +Certplus Root CA G1 +=================== +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV +BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe +Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD +ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN +r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx +Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj +BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv +LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2 +z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc +4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd +4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj +jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+ +ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY +lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG +YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/ +2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F +6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX +CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe +tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC +VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/ ++mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+ +qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +Certplus Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT +AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x +NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0 +cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN +Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud +IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV +HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl +vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +OpenTrust Root CA G1 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx +MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa +Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87 +ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO +YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9 +xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO +9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq +3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi +n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9 +URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr +TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px +N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv +uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK +n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh +X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80 +nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm +GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/ +bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o +4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA +OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx +-----END CERTIFICATE----- + +OpenTrust Root CA G2 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy +MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+ +Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz +4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV +eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt +UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz +3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj +3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz +9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0 +0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT +y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59 +M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI +mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG +S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp +EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ +6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr +gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo +SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0 +YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm +u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK +-----END CERTIFICATE----- + +OpenTrust Root CA G3 +==================== +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X +DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w +ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B +ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf +BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM +BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta +3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +LuxTrust Global Root 2 +====================== +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG +A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh +bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW +MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm +Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 +xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC +wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm +1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm +FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF +wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ +a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U +ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ +MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB +/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 +Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ +FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN +H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW +7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu +ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA +VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR +TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt +/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc +7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I +iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index e6da67d2b3..4b12dde831 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -6,12 +6,14 @@ # ly_get_list_relative_pal_filename(pal_editor_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Private/Editor/Platform/${PAL_PLATFORM_NAME}) +ly_get_list_relative_pal_filename(pal_cafile_include_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Framework/Platform/${PAL_PLATFORM_NAME}) ly_add_target( NAME AWSCore.Static STATIC NAMESPACE Gem FILES_CMAKE awscore_files.cmake + ${pal_cafile_include_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC Include/Public diff --git a/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp b/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp index 8800094b95..4383e0a8ac 100644 --- a/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp +++ b/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp @@ -9,6 +9,10 @@ namespace AWSCore { + namespace Platform + { + Aws::String GetCaCertBundlePath(); + } const char* AwsApiJob::COMPONENT_DISPLAY_NAME = "AWSCoreFramework"; @@ -29,6 +33,14 @@ namespace AWSCore config.userAgent = "/O3DE_AwsApiJob"; config.requestTimeoutMs = 30000; config.connectTimeoutMs = 30000; + + // Instructs the HTTP client where to find the SSL certificate trust store. + // It is required to copy the cacert.pem to the expected file path for running the Android client. + Aws::String caFilePath = Platform::GetCaCertBundlePath(); + if (!caFilePath.empty()) + { + config.caFile = caFilePath; + } } ); }; diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp b/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp new file mode 100644 index 0000000000..b0d97e3ddd --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING +#include +#include + +namespace AWSCore +{ + namespace Platform + { + Aws::String GetCaCertBundlePath() + { + AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath(); + publicStoragePath.append("/certificates/aws/cacert.pem"); + + return publicStoragePath.c_str(); + } + } // namespace Platform +} diff --git a/Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake similarity index 81% rename from Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake rename to Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake index 180b7b9492..22d9681e3f 100644 --- a/Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake @@ -5,4 +5,6 @@ # # -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED TRUE) +set(FILES + GetCertsPath_Android.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp b/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp new file mode 100644 index 0000000000..3bc9739e56 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING + +namespace AWSCore +{ + namespace Platform + { + Aws::String GetCaCertBundlePath() + { + return ""; // no-op + } + } // namespace Platform +} // namespace GridMate diff --git a/Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake similarity index 81% rename from Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake rename to Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake index 929d864fc4..108bdbcff1 100644 --- a/Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake @@ -5,4 +5,6 @@ # # -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake similarity index 81% rename from Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake rename to Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake index 929d864fc4..108bdbcff1 100644 --- a/Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake @@ -5,4 +5,6 @@ # # -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake similarity index 81% rename from Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake rename to Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake index 929d864fc4..108bdbcff1 100644 --- a/Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake @@ -5,4 +5,6 @@ # # -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake new file mode 100644 index 0000000000..108bdbcff1 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 7e2540cf44..7be98ab056 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -425,16 +425,16 @@ namespace AZ { const auto& jobParameters = request.m_jobDescription.m_jobParameters; - if (jobParameters.find(ShaderVariantLoadErrorParam) != jobParameters.end()) + if (jobParameters.contains(ShaderVariantLoadErrorParam)) { AZ_Error(ShaderVariantAssetBuilderName, false, "Error during CreateJobs: %s", jobParameters.at(ShaderVariantLoadErrorParam).c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; return; } - if (jobParameters.find(ShouldExitEarlyFromProcessJobParam) != jobParameters.end()) + if (jobParameters.contains(ShouldExitEarlyFromProcessJobParam)) { - AZ_TracePrintf(ShaderVariantAssetBuilderName, "Doing nothing on behalf of [%s] because it's been overridden by game project.", jobParameters.at(ShaderVariantLoadErrorParam).c_str()); + AZ_TracePrintf(ShaderVariantAssetBuilderName, "Doing nothing on behalf of [%s] because it's been overridden by game project.", jobParameters.at(ShouldExitEarlyFromProcessJobParam).c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; return; } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli index 2c2f956f8f..c979cff128 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli @@ -427,7 +427,7 @@ PixelDepthOffset CalcPixelDepthOffset( float depthFactor, float4 clipOffsetPosition = mul(viewProjectionMatrix, float4(worldOffsetPosition, 1.0)); PixelDepthOffset pdo; - pdo.m_depthCS = clipOffsetPosition.z; + pdo.m_depthCS = clipOffsetPosition.w; pdo.m_depthNDC = clipOffsetPosition.z / clipOffsetPosition.w; pdo.m_worldPosition = worldOffsetPosition; return pdo; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl index fc5684fe7f..99d38463c7 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl @@ -14,6 +14,15 @@ option enum class SkinningMethod { LinearSkinning, DualQuaternion } o_skinningMe option bool o_applyMorphTargets = false; option bool o_applyColorMorphTargets = false; +float3 ReadFloat3FromFloatBuffer(Buffer buffer, uint index) +{ + float3 result; + result.x = buffer[index * 3]; + result.y = buffer[index * 3 + 1]; + result.z = buffer[index * 3 + 2]; + return result; +} + // Apply a morph target delta with three components void ApplyMorphTargetDelta(uint streamOffset, uint vertexIndex, inout float3 modifiedValue) { @@ -162,10 +171,10 @@ void MainCS(uint3 thread_id: SV_DispatchThreadID) return; } - float3 position = InstanceSrg::m_sourcePositions[i]; - float3 normal = InstanceSrg::m_sourceNormals[i]; - float4 tangent = InstanceSrg::m_sourceTangents[i]; - float3 bitangent = InstanceSrg::m_sourceBiTangents[i]; + float3 position = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourcePositions, i); + float3 normal = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourceNormals, i); + float4 tangent = InstanceSrg::m_sourceTangents[i]; + float3 bitangent = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourceBiTangents, i); // Four indices, 16-bits each, stored in 2 32-bit uints uint2 rawIndices = InstanceSrg::m_sourceBlendIndices.Load2(i * 8); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli index 95802ddbb7..066cefdc37 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli @@ -20,10 +20,12 @@ ShaderResourceGroup InstanceSrg : SRG_PerDraw uint m_totalNumberOfThreadsX; // Per-model input - Buffer m_sourcePositions; // POSITION 0 - Buffer m_sourceNormals; // NORMAL 0 + // Positions, normals, and bitangents are all 3-component per-vertex buffers, + // but Metal doesn't support float3 buffers so Buffer is used instead + Buffer m_sourcePositions; // POSITION 0 + Buffer m_sourceNormals; // NORMAL 0 Buffer m_sourceTangents; // TANGENT 0 - Buffer m_sourceBiTangents; // BITANGENT 0 + Buffer m_sourceBiTangents; // BITANGENT 0 ByteAddressBuffer m_sourceBlendIndices; // BLENDINDICES 0 Buffer m_sourceBlendWeights; // BLENDWEIGHTS 0 diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp index e435de7799..438c8c2f28 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp @@ -245,6 +245,29 @@ namespace AZ m_bakedClassificationImage.get(); } + void DiffuseProbeGrid::ResetCullingVisibility() + { + m_cullable.m_isVisible = false; + } + + bool DiffuseProbeGrid::GetIsVisible() const + { + // we need to go through the DiffuseProbeGrid passes at least once in order to initialize + // the RenderObjectSrg, which means we need to be visible until the RenderObjectSrg is created + if (m_renderObjectSrg == nullptr) + { + return true; + } + + // if a bake is in progress we need to make this DiffuseProbeGrid visible + if (!m_textureReadback.IsIdle()) + { + return true; + } + + return m_cullable.m_isVisible; + } + uint32_t DiffuseProbeGrid::GetTotalProbeCount() const { return m_probeCountX * m_probeCountY * m_probeCountZ; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h index 3c5c481fea..06fa8592a3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h @@ -103,6 +103,9 @@ namespace AZ void DecrementRemainingRelocationIterations() { m_remainingRelocationIterations = AZStd::max(0, m_remainingRelocationIterations - 1); } void ResetRemainingRelocationIterations() { m_remainingRelocationIterations = DefaultNumRelocationIterations; } + void ResetCullingVisibility(); + bool GetIsVisible() const; + // compute total number of probes in the grid uint32_t GetTotalProbeCount() const; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp index e8c99a630f..f75c62cd6c 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp @@ -82,7 +82,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -106,7 +106,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -145,7 +145,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -162,7 +162,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendDistanceSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp index 637c655074..748f0b8093 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp @@ -82,7 +82,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -106,7 +106,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -145,7 +145,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -162,7 +162,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendIrradianceSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp index f437b3a1ef..a46ee0e550 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp @@ -95,7 +95,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -119,7 +119,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe irradiance image { @@ -148,7 +148,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see line ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -168,7 +168,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { uint32_t probeCountX; uint32_t probeCountY; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp index 93297fe336..7ddc3f7d68 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp @@ -86,7 +86,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -110,7 +110,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -138,7 +138,7 @@ namespace AZ { RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -154,7 +154,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetClassificationSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp index 5ceb8a197d..a001f60e89 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp @@ -175,6 +175,27 @@ namespace AZ } } + void DiffuseProbeGridFeatureProcessor::OnBeginPrepareRender() + { + for (auto& diffuseProbeGrid : m_realTimeDiffuseProbeGrids) + { + diffuseProbeGrid->ResetCullingVisibility(); + } + } + + void DiffuseProbeGridFeatureProcessor::OnEndPrepareRender() + { + // re-build the list of visible real-time diffuse probe grids + m_visibleRealTimeDiffuseProbeGrids.clear(); + for (auto& diffuseProbeGrid : m_realTimeDiffuseProbeGrids) + { + if (diffuseProbeGrid->GetIsVisible()) + { + m_visibleRealTimeDiffuseProbeGrids.push_back(diffuseProbeGrid); + } + } + } + DiffuseProbeGridHandle DiffuseProbeGridFeatureProcessor::AddProbeGrid(const AZ::Transform& transform, const AZ::Vector3& extents, const AZ::Vector3& probeSpacing) { AZStd::shared_ptr diffuseProbeGrid = AZStd::make_shared(); @@ -215,6 +236,17 @@ namespace AZ m_realTimeDiffuseProbeGrids.erase(itEntry); } + // remove from side list of visible real-time grids + itEntry = AZStd::find_if(m_visibleRealTimeDiffuseProbeGrids.begin(), m_visibleRealTimeDiffuseProbeGrids.end(), [&](AZStd::shared_ptr const& entry) + { + return (entry == probeGrid); + }); + + if (itEntry != m_visibleRealTimeDiffuseProbeGrids.end()) + { + m_visibleRealTimeDiffuseProbeGrids.erase(itEntry); + } + probeGrid = nullptr; } diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h index 4d045ec62d..9771c058ad 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h @@ -76,6 +76,9 @@ namespace AZ // retrieve the side list of probe grids that are using real-time (raytraced) mode DiffuseProbeGridVector& GetRealTimeProbeGrids() { return m_realTimeDiffuseProbeGrids; } + // retrieve the side list of probe grids that are using real-time (raytraced) mode and visible (on screen) + DiffuseProbeGridVector& GetVisibleRealTimeProbeGrids() { return m_visibleRealTimeDiffuseProbeGrids; } + private: AZ_DISABLE_COPY_MOVE(DiffuseProbeGridFeatureProcessor); @@ -96,6 +99,8 @@ namespace AZ void HandleAssetNotification(Data::Asset asset, DiffuseProbeGridTextureNotificationType notificationType); // RPI::SceneNotificationBus::Handler overrides + void OnBeginPrepareRender() override; + void OnEndPrepareRender() override; void OnRenderPipelinePassesChanged(RPI::RenderPipeline* renderPipeline) override; void OnRenderPipelineAdded(RPI::RenderPipelinePtr pipeline) override; void OnRenderPipelineRemoved(RPI::RenderPipeline* pipeline) override; @@ -110,6 +115,9 @@ namespace AZ // side list of diffuse probe grids that are in real-time mode (subset of m_diffuseProbeGrids) DiffuseProbeGridVector m_realTimeDiffuseProbeGrids; + // side list of diffuse probe grids that are in real-time mode and visible (subset of m_realTimeDiffuseProbeGrids) + DiffuseProbeGridVector m_visibleRealTimeDiffuseProbeGrids; + // position structure for the box vertices struct Position { diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp index 8079912363..2ff9c5991e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp @@ -130,7 +130,7 @@ namespace AZ } DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -147,9 +147,9 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor(); - frameGraph.SetEstimatedItemCount(aznumeric_cast(diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().size())); + frameGraph.SetEstimatedItemCount(aznumeric_cast(diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().size())); - for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // TLAS { @@ -254,7 +254,7 @@ namespace AZ rayTracingFeatureProcessor->GetMeshInfoBuffer() && rayTracingFeatureProcessor->GetSubMeshCount()) { - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader // inputs (see line ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -302,7 +302,7 @@ namespace AZ m_rayTracingShaderTable) { // submit the DispatchRaysItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroups[] = { diffuseProbeGrid->GetRayTraceSrg()->GetRHIShaderResourceGroup(), diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp index c6464fcc72..efdfbebcae 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp @@ -86,7 +86,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -103,7 +103,7 @@ namespace AZ // create the Relocation Srgs for each DiffuseProbeGrid, and check to see if any grids need relocation bool needRelocation = false; - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { uint32_t rayTracingDataRevision = rayTracingFeatureProcessor->GetRevision(); if (rayTracingDataRevision != m_rayTracingDataRevision) @@ -134,7 +134,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -162,7 +162,7 @@ namespace AZ { RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -182,7 +182,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetRelocationSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp index 6f6f83dda2..a50d0084f1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp @@ -94,7 +94,12 @@ namespace AZ { continue; } - + + if (!diffuseProbeGrid->GetIsVisible()) + { + continue; + } + // probe irradiance image { if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked) @@ -182,6 +187,11 @@ namespace AZ continue; } + if (!diffuseProbeGrid->GetIsVisible()) + { + continue; + } + // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() of ShaderResourceGroupData.cpp) diffuseProbeGrid->UpdateRenderObjectSrg(); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp index 3e808a99c1..8931a4feb1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp @@ -22,7 +22,9 @@ namespace AZ AZ_Assert(m_readbackState == DiffuseProbeGridReadbackState::Idle, "DiffuseProbeGridTextureReadback is already processing a readback request"); m_callback = callback; - m_readbackState = DiffuseProbeGridReadbackState::Irradiance; + + m_remainingInitializationFrames = DefaultNumInitializationFrames; + m_readbackState = DiffuseProbeGridReadbackState::Initializing; } void DiffuseProbeGridTextureReadback::Update(const AZ::Name& passName) @@ -32,6 +34,19 @@ namespace AZ return; } + if (m_readbackState == DiffuseProbeGridReadbackState::Initializing) + { + if (m_remainingInitializationFrames > 0) + { + // still in the initialization state to allow the irradiance textures to settle, decrement the frame count + m_remainingInitializationFrames--; + return; + } + + // settling complete, move to the irradiance readback state to begin the readback process + m_readbackState = DiffuseProbeGridReadbackState::Irradiance; + } + if (m_attachmentReadback.get() && m_attachmentReadback->GetReadbackState() > RPI::AttachmentReadback::ReadbackState::Idle) { // still processing previous request diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h index c399fac534..b0d35069a7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h @@ -20,6 +20,7 @@ namespace AZ enum class DiffuseProbeGridReadbackState { Idle, + Initializing, Irradiance, Distance, Relocation, @@ -39,6 +40,8 @@ namespace AZ void Update(const AZ::Name& passName); void FrameBegin(AZ::RPI::Pass::FramePrepareParams& params); + bool IsIdle() const { return m_readbackState == DiffuseProbeGridReadbackState::Idle; } + private: DiffuseProbeGrid* m_diffuseProbeGrid = nullptr; @@ -50,6 +53,10 @@ namespace AZ AZ::RPI::AttachmentReadback::ReadbackResult m_distanceReadbackResult; AZ::RPI::AttachmentReadback::ReadbackResult m_relocationReadbackResult; AZ::RPI::AttachmentReadback::ReadbackResult m_classificationReadbackResult; + + // number of frames to delay before starting the texture readbacks, this allows the textures to settle + static constexpr int32_t DefaultNumInitializationFrames = 50; + int32_t m_remainingInitializationFrames = DefaultNumInitializationFrames; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index 3ec7bd4186..36e4689325 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -266,6 +266,10 @@ namespace AZ { AZ_Assert(probe.get(), "SetProbeCubeMap called with an invalid handle"); probe->SetCubeMapImage(cubeMapImage, relativePath); + + // notify the MeshFeatureProcessor that the reflection probe changed + MeshFeatureProcessor* meshFeatureProcessor = GetParentScene()->GetFeatureProcessor(); + meshFeatureProcessor->UpdateMeshReflectionProbes(); } void ReflectionProbeFeatureProcessor::SetProbeTransform(const ReflectionProbeHandle& probe, const AZ::Transform& transform) diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp index 75d079c937..8ef82dfac4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp @@ -118,7 +118,29 @@ namespace AZ } m_inputBufferAssets[static_cast(inputStream)] = bufferAsset; - m_inputBuffers[static_cast(inputStream)] = RPI::Buffer::FindOrCreate(bufferAsset); + Data::Instance buffer = RPI::Buffer::FindOrCreate(bufferAsset); + m_inputBuffers[static_cast(inputStream)] = buffer; + + // Create a buffer view to use as input to the skinning shader + AZ::RHI::Ptr bufferView = RHI::Factory::Get().CreateBufferView(); + bufferView->SetName(Name{ AZStd::string(buffer->GetBufferView()->GetName().GetStringView()) + "_SkinningInputBufferView" }); + RHI::BufferViewDescriptor bufferViewDescriptor = bufferAsset->GetBufferViewDescriptor(); + + // 3-component float buffers are not supported on metal for non-input assembly buffer views, so use a float view instead + if (bufferViewDescriptor.m_elementFormat == RHI::Format::R32G32B32_FLOAT) + { + // Use one float per element, with 3x as many elements + bufferViewDescriptor = RHI::BufferViewDescriptor::CreateTyped( + bufferViewDescriptor.m_elementOffset * 3, bufferViewDescriptor.m_elementCount * 3, RHI::Format::R32_FLOAT); + } + + [[maybe_unused]] RHI::ResultCode resultCode = + bufferView->Init(*buffer->GetRHIBuffer(), bufferViewDescriptor); + AZ_Error( + "SkinnedMeshInputBuffers", resultCode == RHI::ResultCode::Success, + "Failed to initialize buffer view for skinned mesh input."); + + m_bufferViews[static_cast(inputStream)] = bufferView; } void SkinnedMeshInputLod::SetStaticBufferAsset(const Data::Asset bufferAsset, SkinnedMeshStaticVertexStreams staticStream) @@ -315,7 +337,7 @@ namespace AZ [[maybe_unused]] bool success = false; if (m_lods[lodIndex].m_inputBuffers[inputStream]) { - success = perInstanceSRG->SetBufferView(srgIndex, m_lods[lodIndex].m_inputBuffers[inputStream]->GetBufferView()); + success = perInstanceSRG->SetBufferView(srgIndex, m_lods[lodIndex].m_bufferViews[inputStream].get()); } AZ_Error("SkinnedMeshInputBuffers", success, "Failed to bind buffer view for %s", streamInfo.m_bufferName.GetCStr()); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h index 72d0e3c69c..7f042e58cb 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h @@ -91,6 +91,10 @@ namespace AZ }; LodData m_lodData; + //! Flag indicating if the object is visible in any view, meaning it passed the culling tests in the previous frame. + //! This flag must be manually cleared by the Cullable object every frame. + bool m_isVisible = false; + //! Flag indicating if the object is hidden, i.e., was specifically marked as //! something that shouldn't be rendered, regardless of its actual position relative to the camera bool m_isHidden = false; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp index cd1b0e925a..c78d8e8169 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp @@ -339,6 +339,7 @@ namespace AZ { numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view); ++numVisibleCullables; + c->m_isVisible = true; } } } @@ -374,6 +375,7 @@ namespace AZ { numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view); ++numVisibleCullables; + c->m_isVisible = true; } } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp index 3923136bcc..5325ba911d 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace AZ { @@ -55,21 +56,15 @@ namespace AZ case PhotometricUnit::Lux: return 0.0f; case PhotometricUnit::Ev100Illuminance: - return -10.0f; + return AZStd::numeric_limits::lowest(); } return 0.0f; } float DirectionalLightComponentConfig::GetIntensityMax() const { - switch (m_intensityMode) - { - case PhotometricUnit::Lux: - return 1'000'000.0f; - case PhotometricUnit::Ev100Illuminance: - return 20.0f; - } - return 0.0f; + // While there is no hard-max, a max must be included when there is a hard min. + return AZStd::numeric_limits::max(); } float DirectionalLightComponentConfig::GetIntensitySoftMin() const diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp index 81e87f3cb5..c27faa2241 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp @@ -154,19 +154,19 @@ namespace AZ ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled) ->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_predictionSampleCount, "Prediction sample count", - "Sample Count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.") + "Sample count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 16) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled) ->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering sample count", - "It is used only when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.") + "This is only used when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 64) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "Pcf method", + Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "PCF method", "Type of PCF to use.\n" " Bicubic: a smooth, fixed-size kernel \n" " Boundary search: do several taps to first determine if we are on a shadow boundary\n") @@ -176,8 +176,8 @@ namespace AZ ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_esmExponent, "Esm Exponent", - "Exponent used by Esm shadows. " + Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_esmExponent, "ESM exponent", + "Exponent used by ESM shadows. " "Larger values increase the sharpness of the border between lit and unlit areas.") ->Attribute(Edit::Attributes::Min, 50.0f) ->Attribute(Edit::Attributes::Max, 5000.0f) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp index 8163dcfe20..4d43c23e25 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp @@ -57,74 +57,74 @@ namespace AZ editContext->Class("DirectionalLightComponentConfig", "") ->ClassElement(Edit::ClassElements::EditorData, "") ->DataElement(Edit::UIHandlers::Color, &DirectionalLightComponentConfig::m_color, "Color", "Color of the light") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying light values in lux or Ev100") - ->EnumAttribute(PhotometricUnit::Lux, "Lux") - ->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues) + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying light values in lux or Ev100") + ->EnumAttribute(PhotometricUnit::Lux, "Lux") + ->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100") + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues) ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.") - ->Attribute(Edit::Attributes::Min, &DirectionalLightComponentConfig::GetIntensityMin) - ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::GetIntensityMax) - ->Attribute(Edit::Attributes::SoftMin, &DirectionalLightComponentConfig::GetIntensitySoftMin) - ->Attribute(Edit::Attributes::SoftMax, &DirectionalLightComponentConfig::GetIntensitySoftMax) - ->Attribute(Edit::Attributes::Suffix, &DirectionalLightComponentConfig::GetIntensitySuffix) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_angularDiameter, "Angular Diameter", "Angular Diameter of the directional light in degrees. The sun is about 0.5.") - ->Attribute(Edit::Attributes::Min, 0.0f) - ->Attribute(Edit::Attributes::Max, 5.0f) - ->Attribute(Edit::Attributes::SoftMax, 1.0f) - ->Attribute(Edit::Attributes::Suffix, " deg") + ->Attribute(Edit::Attributes::Min, &DirectionalLightComponentConfig::GetIntensityMin) + ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::GetIntensityMax) + ->Attribute(Edit::Attributes::SoftMin, &DirectionalLightComponentConfig::GetIntensitySoftMin) + ->Attribute(Edit::Attributes::SoftMax, &DirectionalLightComponentConfig::GetIntensitySoftMax) + ->Attribute(Edit::Attributes::Suffix, &DirectionalLightComponentConfig::GetIntensitySuffix) + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_angularDiameter, "Angular diameter", "Angular diameter of the directional light in degrees. The sun is about 0.5.") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 5.0f) + ->Attribute(Edit::Attributes::SoftMax, 1.0f) + ->Attribute(Edit::Attributes::Suffix, " deg") ->ClassElement(AZ::Edit::ClassElements::Group, "Shadow") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(Edit::UIHandlers::EntityId, &DirectionalLightComponentConfig::m_cameraEntityId, "Camera", "Entity of the camera for cascaded shadowmap view frustum.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_shadowFarClipDistance, "Shadow Far Clip", "Shadow sepcific far clip distance.") + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_shadowFarClipDistance, "Shadow far clip", "Shadow specific far clip distance.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowmapSize, "Shadowmap Size", "Width/Height of shadowmap") + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowmapSize, "Shadowmap size", "Width/Height of shadowmap") ->EnumAttribute(ShadowmapSize::Size256, " 256") ->EnumAttribute(ShadowmapSize::Size512, " 512") ->EnumAttribute(ShadowmapSize::Size1024, "1024") ->EnumAttribute(ShadowmapSize::Size2048, "2048") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_cascadeCount, "Cascade Count", "Number of cascades") + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_cascadeCount, "Cascade count", "Number of cascades") ->Attribute(Edit::Attributes::Min, 1) ->Attribute(Edit::Attributes::Max, Shadow::MaxNumberOfCascades) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_isShadowmapFrustumSplitAutomatic, "Split Automatic", + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_isShadowmapFrustumSplitAutomatic, "Automatic splitting", "Switch splitting of shadowmap frustum to cascades automatically or not.") - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowmapFrustumSplitSchemeRatio, "Split Ratio", + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowmapFrustumSplitSchemeRatio, "Split ratio", "Ratio to lerp between the two types of frustum splitting scheme.\n" - "0 = Uniform scheme which will split the Frustum evenly across all cascades.\n" + "0 = Uniform scheme which will split the frustum evenly across all cascades.\n" "1 = Logarithmic scheme which is designed to split the frustum in a logarithmic fashion " "in order to enable us to produce a more optimal perspective aliasing across the frustum.") ->Attribute(Edit::Attributes::Min, 0.f) ->Attribute(Edit::Attributes::Max, 1.f) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitManual) - ->DataElement(Edit::UIHandlers::Vector4, &DirectionalLightComponentConfig::m_cascadeFarDepths, "Far Depth Cascade", - "Far Depth of each cascade. The value of the index greater than or equal to cascade count is ignored.") + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitManual) + ->DataElement(Edit::UIHandlers::Vector4, &DirectionalLightComponentConfig::m_cascadeFarDepths, "Far depth cascade", + "Far depth of each cascade. The value of the index greater than or equal to cascade count is ignored.") ->Attribute(Edit::Attributes::Min, 0.01f) ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::m_shadowFarClipDistance) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitAutomatic) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_groundHeight, "Ground Height", + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_groundHeight, "Ground height", "Height of the ground. Used to correct position of cascades.") ->Attribute(Edit::Attributes::Suffix, " m") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsCascadeCorrectionDisabled) + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsCascadeCorrectionDisabled) ->DataElement(Edit::UIHandlers::CheckBox, - &DirectionalLightComponentConfig::m_isCascadeCorrectionEnabled, "Enable Cascade Correction?", + &DirectionalLightComponentConfig::m_isCascadeCorrectionEnabled, "Cascade correction", "Enable position correction of cascades to optimize the appearance for certain camera positions.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->DataElement(Edit::UIHandlers::CheckBox, - &DirectionalLightComponentConfig::m_isDebugColoringEnabled, "Enable Debug Coloring?", + &DirectionalLightComponentConfig::m_isDebugColoringEnabled, "Debug coloring", "Enable coloring to see how cascades places 0:red, 1:green, 2:blue, 3:yellow.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowFilterMethod, "Shadow Filter Method", + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowFilterMethod, "Shadow filter method", "Filtering method of edge-softening of shadows.\n" - " None: no filtering\n" - " PCF: Percentage-Closer Filtering\n" - " ESM: Exponential Shadow Maps\n" + " None: No filtering\n" + " PCF: Percentage-closer filtering\n" + " ESM: Exponential shadow maps\n" " ESM+PCF: ESM with a PCF fallback\n" "For BehaviorContext (or TrackView), None=0, PCF=1, ESM=2, ESM+PCF=3") ->EnumAttribute(ShadowFilterMethod::None, "None") @@ -132,7 +132,7 @@ namespace AZ ->EnumAttribute(ShadowFilterMethod::Esm, "ESM") ->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_boundaryWidth, "Softening Boundary Width", + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_boundaryWidth, "Softening boundary width", "Width of the boundary between shadowed area and lit one. " "Units are in meters. " "If this is 0, softening edge is disabled.") @@ -141,29 +141,29 @@ namespace AZ ->Attribute(Edit::Attributes::Suffix, " m") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count", - "Sample Count for prediction of whether the pixel is on the boundary. " + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_predictionSampleCount, "Prediction sample count", + "Sample count for prediction of whether the pixel is on the boundary. " "Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 16) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count", - "It is used only when the pixel is predicted as on the boundary. " + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count", + "This is used only when the pixel is predicted as on the boundary. " "Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 64) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_pcfMethod, "Pcf Method", - "Type of Pcf to use.\n" + Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_pcfMethod, "Pcf method", + "Type of PCF to use.\n" " Bicubic: a smooth, fixed-size kernel \n" " Boundary search: do several taps to first determine if we are on a shadow boundary\n") - ->EnumAttribute(PcfMethod::Bicubic, "Bicubic") - ->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled); + ->EnumAttribute(PcfMethod::Bicubic, "Bicubic") + ->EnumAttribute(PcfMethod::BoundarySearch, "Boundary search") + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled); ; } diff --git a/Gems/ImGui/Code/Include/ImGuiBus.h b/Gems/ImGui/Code/Include/ImGuiBus.h index ea7fe1631e..06a3b472da 100644 --- a/Gems/ImGui/Code/Include/ImGuiBus.h +++ b/Gems/ImGui/Code/Include/ImGuiBus.h @@ -8,6 +8,7 @@ #pragma once #include +#include // Forward Declares struct ImVec2; @@ -86,9 +87,19 @@ namespace ImGui virtual void SetImGuiRenderResolution(const ImVec2& res) = 0; virtual void OverrideRenderWindowSize(uint32_t width, uint32_t height) = 0; virtual void RestoreRenderWindowSizeToDefault() = 0; + virtual void ToggleThroughImGuiVisibleState() = 0; virtual void SetDpiScalingFactor(float dpiScalingFactor) = 0; virtual float GetDpiScalingFactor() const = 0; virtual void Render() = 0; + + using ImGuiSetEnabledEvent = AZ::Event; + ImGuiSetEnabledEvent m_setEnabledEvent; + + // interface + void ConnectImGuiSetEnabledChangedHandler(ImGuiSetEnabledEvent::Handler& handler) + { + handler.Connect(m_setEnabledEvent); + } }; class IImGuiManagerRequests @@ -101,19 +112,30 @@ namespace ImGui }; using ImGuiManagerBus = AZ::EBus; - // Bus for getting notifications from the IMGUI Entity Outliner - class IImGuiEntityOutlinerNotifcations : public AZ::EBusTraits + class IImGuiManagerNotifications : public AZ::EBusTraits { public: - static const char* GetUniqueName() { return "IImGuiEntityOutlinerNotifcations"; } static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using Bus = AZ::EBus; + using Bus = AZ::EBus; + + virtual void ImGuiSetEnabled( [[maybe_unused]] bool enabled) {} + }; + using ImGuiManagerNotificationBus = AZ::EBus; + + // Bus for getting notifications from the IMGUI Entity Outliner + class IImGuiEntityOutlinerNotifications : public AZ::EBusTraits + { + public: + static const char* GetUniqueName() { return "IImGuiEntityOutlinerNotifications"; } + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + using Bus = AZ::EBus; // Callback for game code to handle targetting an IMGUI entity virtual void OnImGuiEntityOutlinerTarget(AZ::EntityId target) { (void)target; } }; - typedef AZ::EBus ImGuiEntityOutlinerNotifcationBus; + typedef AZ::EBus ImGuiEntityOutlinerNotificationBus; // a pair of an entity id, and a typeid, used to represent component rtti type info typedef AZStd::pair ImGuiEntComponentId; diff --git a/Gems/ImGui/Code/Source/ImGuiManager.cpp b/Gems/ImGui/Code/Source/ImGuiManager.cpp index 42c8d3929c..7b2506fbcb 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.cpp +++ b/Gems/ImGui/Code/Source/ImGuiManager.cpp @@ -738,8 +738,15 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) } m_menuBarStatusChanged = true; + m_setEnabledEvent.Signal(m_clientMenuBarState == DisplayState::Hidden); } +void ImGuiManager::ToggleThroughImGuiVisibleState() +{ + ToggleThroughImGuiVisibleState(-1); +} + + void ImGuiManager::RenderImGuiBuffers(const ImVec2& scaleRects) { ImGui::ImGuiContextScope contextScope(m_imguiContext); diff --git a/Gems/ImGui/Code/Source/ImGuiManager.h b/Gems/ImGui/Code/Source/ImGuiManager.h index 1509f27c57..02af3d0c09 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.h +++ b/Gems/ImGui/Code/Source/ImGuiManager.h @@ -60,6 +60,7 @@ namespace ImGui void SetDpiScalingFactor(float dpiScalingFactor) override; float GetDpiScalingFactor() const override; void Render() override; + void ToggleThroughImGuiVisibleState() override; // -- ImGuiManagerBus Interface ------------------------------------------------------------------- // -- AzFramework::InputChannelEventListener and AzFramework::InputTextEventListener Interface ------------ diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp index 2f996f5768..d9d81c24f2 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp @@ -465,7 +465,7 @@ namespace ImGui ImGui::BeginGroup(); if (ImGui::SmallButton(AZStd::string::format("-View #%03d-##%s", ++instanceCount, meshInstance.first.ToString().c_str()).c_str())) { - ImGuiEntityOutlinerNotifcationBus::Broadcast(&IImGuiEntityOutlinerNotifcations::OnImGuiEntityOutlinerTarget, meshInstance.first); + ImGuiEntityOutlinerNotificationBus::Broadcast(&IImGuiEntityOutlinerNotifications::OnImGuiEntityOutlinerTarget, meshInstance.first); } // Build the Label String. ImGui::SameLine(); diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp index 9994851faa..eb918041f7 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp @@ -571,7 +571,26 @@ namespace ImGui // End LY Common Tools menu ImGui::EndMenu(); } + const int labelSize{ 100 }; + const int buttonSize{ 40 }; ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiMainMenuUpdate); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - labelSize); + float backgroundHeight = ImGui::GetTextLineHeight() + 3; + ImVec2 cursorPos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled( + cursorPos, ImVec2(cursorPos.x + labelSize, cursorPos.y + backgroundHeight), IM_COL32(0, 115, 187, 255)); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - labelSize); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 1); + ImGui::Text("ImGui:ON"); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - buttonSize); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 0, 0, 255)); + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(255, 255, 255, 255)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(128, 128, 128, 255)); + if (ImGui::SmallButton("home")) + { + ImGuiManagerBus::Broadcast(&IImGuiManager::ToggleThroughImGuiVisibleState); + } + ImGui::PopStyleColor(3); ImGui::EndMainMenuBar(); } diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp index aca52af238..57502296ae 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp @@ -590,7 +590,7 @@ namespace ImGui if (ImGui::SmallButton(targetLabel.c_str())) { // Send EBUS event out to Target an Entity. Up to game code to implement. - ImGuiEntityOutlinerNotifcationBus::Broadcast(&IImGuiEntityOutlinerNotifcations::OnImGuiEntityOutlinerTarget, node->m_entityId); + ImGuiEntityOutlinerNotificationBus::Broadcast(&IImGuiEntityOutlinerNotifications::OnImGuiEntityOutlinerTarget, node->m_entityId); } } diff --git a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake index af355b0a51..34f67ccedd 100644 --- a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake +++ b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake @@ -5,6 +5,15 @@ # # +add_custom_command(TARGET LmbrCentral.Editor POST_BUILD + COMMAND "${CMAKE_COMMAND}" -P "${LY_ROOT_FOLDER}/cmake/Platform/Mac/RPathChange.cmake" + "$/lrelease" + @executable_path/../Frameworks + @executable_path + COMMENT "Patching lrelease..." + VERBATIM +) + set(lrelease_files ${QT_LRELEASE_EXECUTABLE} ) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp index a45967a16c..48a68a30a5 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp @@ -22,7 +22,7 @@ namespace LmbrCentral { AZ_CLASS_ALLOCATOR_IMPL(EditorTubeShapeComponentMode, AZ::SystemAllocator, 0) - static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.amazon.action.tubeshape.reset_radii", 0x0f2ef8e2); + static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0x0f2ef8e2); static const char* const s_resetRadiiTitle = "Reset Radii"; static const char* const s_resetRadiiDesc = "Reset all variable radius values to the default"; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index 421d9875bc..bf4fd81ef1 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -178,6 +178,18 @@ namespace Multiplayer void MultiplayerEditorConnection::OnDisconnect([[maybe_unused]] AzNetworking::IConnection* connection, [[maybe_unused]] DisconnectReason reason, [[maybe_unused]] TerminationEndpoint endpoint) { - ; + bool editorLaunch = false; + if (auto console = AZ::Interface::Get(); console) + { + console->GetCvarValue("editorsv_launch", editorLaunch); + } + + if (editorsv_isDedicated && editorLaunch && m_networkEditorInterface->GetConnectionSet().GetConnectionCount() == 1) + { + if (m_networkEditorInterface->GetPort() != 0) + { + m_networkEditorInterface->StopListening(); + } + } } } diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index aae363f0d2..7977a39443 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -151,7 +151,7 @@ namespace Multiplayer AZStd::queue m_pendingConnectionTickets; AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 }; - HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId; + HostFrameId m_lastReplicatedHostFrameId = HostFrameId(0); double m_serverSendAccumulator = 0.0; float m_renderBlendFactor = 0.0f; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp index 2272f43a08..1b21dca50a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp @@ -123,20 +123,23 @@ namespace Multiplayer bool PropertyPublisher::PrepareUpdateEntityRecord() { - // If we reach the maximum outstanding records, reset the replication state + bool didPrepare = true; if (m_sentRecords.size() >= net_EntityReplicatorRecordsMax) { - return PrepareAddEntityRecord(); + // If we reach the maximum outstanding records, reset the replication state + didPrepare = PrepareAddEntityRecord(); } - - // We need to clear out old records, and build up a list of everything that has changed since the last acked packet - m_sentRecords.push_front(m_pendingRecord); - auto iter = m_sentRecords.begin(); - ++iter; // Consider everything after the record we are going to send - for (; iter != m_sentRecords.end(); ++iter) + else { - // Sequence wasn't acked, so we need to send these bits again - m_pendingRecord.Append(*iter); + // We need to clear out old records, and build up a list of everything that has changed since the last acked packet + m_sentRecords.push_front(m_pendingRecord); + auto iter = m_sentRecords.begin(); + ++iter; // Consider everything after the record we are going to send + for (; iter != m_sentRecords.end(); ++iter) + { + // Sequence wasn't acked, so we need to send these bits again + m_pendingRecord.Append(*iter); + } } // Don't send predictable properties back to the Autonomous unless we correct them @@ -145,7 +148,7 @@ namespace Multiplayer m_pendingRecord.Subtract(m_netBindComponent->GetPredictableRecord()); } - return true; + return didPrepare; } bool PropertyPublisher::PrepareDeleteEntityRecord() diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp index eecd4915e7..1c59c70867 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp @@ -191,6 +191,8 @@ namespace Multiplayer bool ReplicationRecord::ContainsAuthorityToClientBits() const { + // Check != Authority here since several modes require information about client updates + // (i.e. Autonomous when performing corrections) return (m_remoteNetEntityRole != NetEntityRole::Authority) || (m_remoteNetEntityRole == NetEntityRole::InvalidRole); } diff --git a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp index c084cfa6e0..9624338f5d 100644 --- a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp @@ -28,10 +28,10 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.amazon.action.physx.setdimensionssubmode", 0x77b70dd6); - const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.amazon.action.physx.setoffsetsubmode", 0xc06132e5); - const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.amazon.action.physx.setrotationsubmode", 0xc4225918); - const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.amazon.action.physx.resetsubmode", 0xb70b120e); + const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x77b70dd6); + const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0xc06132e5); + const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xc4225918); + const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0xb70b120e); } AZ_CLASS_ALLOCATOR_IMPL(ColliderComponentMode, AZ::SystemAllocator, 0); diff --git a/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp b/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp index 4da6e8b892..27feae137c 100644 --- a/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp @@ -23,8 +23,8 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 GoToNextModeActionUri = AZ_CRC("com.amazon.action.physx.joint.nextmode", 0xe9cf4ed6); - const AZ::Crc32 GoToPrevModeActionUri = AZ_CRC("com.amazon.action.physx.joint.prevmode", 0xe70f8daa); + const AZ::Crc32 GoToNextModeActionUri = AZ_CRC("com.o3de.action.physx.joint.nextmode", 0xe9cf4ed6); + const AZ::Crc32 GoToPrevModeActionUri = AZ_CRC("com.o3de.action.physx.joint.prevmode", 0xe70f8daa); } const AZStd::string EditorJointComponentMode::s_parameterAngularPair = "Twist Limits"; diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp index e698fcc298..2bc3a91a96 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp @@ -58,16 +58,6 @@ namespace ScriptCanvasEditor required.push_back(AZ_CRC("ScriptCanvasService", 0x41fd58f3)); } - ScriptCanvas::Grammar::Context* EditorAssetSystemComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* EditorAssetSystemComponent::GetTranslationContext() - { - return &m_translationContext; - } - void EditorAssetSystemComponent::Init() { } @@ -79,16 +69,10 @@ namespace ScriptCanvasEditor AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); EditorAssetConversionBus::Handler::BusConnect(); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void EditorAssetSystemComponent::Deactivate() { - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - EditorAssetConversionBus::Handler::BusDisconnect(); AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); m_editorAssetRegistry.Unregister(); diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h index 4a55a35908..84b10ff17c 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h @@ -12,11 +12,6 @@ #include "EditorAssetConversionBus.h" #include #include - -#include -#include -#include -#include #include namespace ScriptCanvasEditor @@ -26,8 +21,6 @@ namespace ScriptCanvasEditor class EditorAssetSystemComponent : public AZ::Component , public EditorAssetConversionBus::Handler - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler , private AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler { public: @@ -60,20 +53,10 @@ namespace ScriptCanvasEditor AZ::Outcome CreateLuaAsset(const AZ::Data::Asset& editAsset, AZStd::string_view graphPathForRawLuaFile) override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler... - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler... - ScriptCanvas::Translation::Context* GetTranslationContext() override; - - ScriptCanvas::AssetRegistry& GetAssetRegistry(); private: - ScriptCanvas::AssetRegistry m_editorAssetRegistry; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; - + ScriptCanvas::AssetRegistry m_editorAssetRegistry; EditorAssetSystemComponent(const EditorAssetSystemComponent&) = delete; }; } diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp index 2f30106707..b37d5c1da4 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp @@ -104,9 +104,6 @@ namespace ScriptCanvasBuilder m_sharedHandlers = HandleAssetTypes(); AssetHandlers workerHandlers(m_sharedHandlers); m_scriptCanvasBuilder.Activate(workerHandlers); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void PluginComponent::Deactivate() @@ -116,18 +113,6 @@ namespace ScriptCanvasBuilder AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::UnregisterSourceAssetType, azrtti_typeid()); m_scriptCanvasBuilder.BusDisconnect(); m_sharedHandlers.DeleteOwnedHandlers(); - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - } - - ScriptCanvas::Grammar::Context* PluginComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* PluginComponent::GetTranslationContext() - { - return &m_translationContext; } void PluginComponent::Reflect(AZ::ReflectContext* context) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h index 5d57863ec3..ff904d195a 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h @@ -12,18 +12,11 @@ #include #include "ScriptCanvasBuilderWorker.h" -#include -#include -#include -#include - namespace ScriptCanvasBuilder { //! ScriptCanvasBuilder is responsible for turning editor ScriptCanvas Assets into runtime script canvas assets class PluginComponent : public AZ::Component - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler { public: AZ_COMPONENT(PluginComponent, "{F8286B21-E751-4745-8BC4-512F190215FF}") @@ -42,19 +35,9 @@ namespace ScriptCanvasBuilder void Deactivate() override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler - ScriptCanvas::Translation::Context* GetTranslationContext() override; - private: PluginComponent(const PluginComponent&) = delete; - SharedHandlers m_sharedHandlers; - Worker m_scriptCanvasBuilder; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 8250eb1763..3f9c5cc8a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include // Version Conversion includes @@ -2335,6 +2333,11 @@ namespace ScriptCanvas } } + bool Node::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, [[maybe_unused]] const Slot& inputSlot) const + { + return true; + } + void Node::CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const { for (const Slot& slot : m_slots) @@ -2949,45 +2952,6 @@ namespace ScriptCanvas } } - void Node::SetInput(const Datum& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Datum&& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Node& node, const SlotId& id, const Datum& input) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - node.SetInput(input, id); - } - - void Node::SetInput(Node& node, const SlotId& id, Datum&& input) - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Node::SetInput"); - - node.SetInput(AZStd::move(input), id); - } - AZStd::string Node::GetDebugName() const { if (GetEntityId().IsValid()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index 55379e29b9..614494883a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -479,7 +479,10 @@ namespace ScriptCanvas Node(const Node&); // Needed just for DLL linkage. Does not perform a copy Node& operator=(const Node&); // Needed just for DLL linkage. Does not perform a copy + virtual bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const; + virtual void CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; + virtual bool ContainsReferencesToVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; Graph* GetGraph() const; @@ -841,9 +844,6 @@ namespace ScriptCanvas void SignalSlotsReordered(); - static void SetInput(Node& node, const SlotId& id, const Datum& input); - static void SetInput(Node& node, const SlotId& id, Datum&& input); - // Will ignore any references and return the Datum that the slot represents. void ModifyUnderlyingSlotDatum(const SlotId& id, ModifiableDatumView& datumView); @@ -995,9 +995,6 @@ protected: void SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId); void SetGraphEntityId(AZ::EntityId graphEntityId); - virtual void SetInput(const Datum& input, const SlotId& id); - virtual void SetInput(Datum&& input, const SlotId& id); - bool SlotExists(AZStd::string_view name, const SlotDescriptor& slotDescriptor) const; bool IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set& path) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index f3d6070ac6..01b754506c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -9,8 +9,6 @@ #include #include -#include -#include namespace NodeableOutCpp { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp index 5ec40d8e5f..db0cf8e589 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp index c9e2e3acc6..882804de36 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 348c89f45f..4ccb462a5d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -32,7 +32,6 @@ #include "AbstractCodeModel.h" #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" @@ -670,6 +669,28 @@ namespace ScriptCanvas return AddVariable(Datum(type), rawName); } + void AbstractCodeModel::CheckForKnownNullDereference(ExecutionTreeConstPtr execution, const ExecutionInput& input, const Slot& inputSlot) + { + if (Data::IsValueType(inputSlot.GetDataType()) + || !execution->GetId().m_node + || !execution->GetId().m_slot + || (input.m_value && !input.m_value->m_datum.Empty())) + { + return; + } + + if (!input.m_value) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, "Internal Error: CheckForKnownNullDereference called with input with no m_value"); + return; + } + + if (!execution->GetId().m_node->CanAcceptNullInput(*execution->GetId().m_slot, inputSlot)) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, ParseErrors::NullInputKnown); + } + } + void AbstractCodeModel::CheckConversion(ConversionByIndex& conversion, VariableConstPtr source, size_t index, const Data::Type& targetType) { const Data::Type& sourceType = source->m_datum.GetType(); @@ -698,7 +719,7 @@ namespace ScriptCanvas } AZStd::string AbstractCodeModel::CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut) @@ -2422,17 +2443,17 @@ namespace ScriptCanvas ExecutionTreePtr start = OpenScope(nullptr, startNode, nullptr); start->SetSymbol(Symbol::FunctionDefinition); + m_start = start; // cache the function definition if (!m_subgraphStartCalls.empty()) { - m_start = start; - + // call OnGraphStart on all the member nodeables first for (auto node : m_subgraphStartCalls) { ExecutionTreePtr childStartCall = CreateChild(start, node, nullptr); childStartCall->SetSymbol(Symbol::FunctionCall); childStartCall->SetName(k_OnGraphStartFunctionName); - childStartCall->MarkStart(); + childStartCall->MarkStartCall(); auto lexicalScopeOutcome = node->GetFunctionCallLexicalScope(nullptr); @@ -2478,11 +2499,13 @@ namespace ScriptCanvas } } + // ExecutionTreePtr start is now either the last child start() call, or the beginning of the function block, + // either way, parsing can continue from the ExecutionTreePtr start. + if (!outSlots.empty()) { start->AddChild({ outSlots[0], {}, nullptr }); - start->MarkStart(); - + ParseExecutionMultipleOutSyntaxSugar(start, outNodes, outSlots); PostParseProcess(start); PostParseErrorDetect(start); @@ -2490,24 +2513,10 @@ namespace ScriptCanvas if (!IsErrorFree()) { start->Clear(); - - if (m_start) - { - m_start->Clear(); - } - + m_start->Clear(); AddError(AZ::EntityId{}, nullptr, ScriptCanvas::ParseErrors::StartNodeFailedToParse); return; } - - if (!m_start) - { - m_start = start; - } - } - else - { - // add warning or notification on useless start node? } if (m_start) @@ -4297,10 +4306,7 @@ namespace ScriptCanvas void AbstractCodeModel::ParseInputDatum(ExecutionTreePtr execution, const Slot& input) { - // \todo look for crossed lines in inferred functions, because sometimes, rather than the input - // being named of the result of the output that emitted it, it will be the name of the inferred function - // parameter ---> make a map of node output to function input names - AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input should have been handled already"); + AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input is not handled in AbstractCodeModel::ParseInputDatum"); auto nodes = execution->GetId().m_node->GetConnectedNodes(input); if (nodes.empty()) @@ -4310,17 +4316,6 @@ namespace ScriptCanvas execution->AddInput({ &input, variable, DebugDataSource::FromVariable(input.GetId(), input.GetDataType(), variable->m_sourceVariableId) }); CheckConversion(execution->ModConversions(), variable, execution->GetInputCount() - 1, input.GetDataType()); } - // This concept may never actually be possible -// else if (RequiresCreationFunction(input.GetDataType().GetType())) -// { -// AddError(execution, aznew NotYetImplemented( -// "1: finish input created by name when connected to other nodes" -// "2: add the name to the scope" -// "3: and check inputs be re-used, common constructors like zero/1, etc" -// "4: read the variable name if it is present instead of creating it" -// "5: check for entity references to self and other member slice variables" -// "6: mark the variable with RequiredCreationFunction()")); -// } else { auto variableDatum = input.FindDatum(); @@ -4357,26 +4352,30 @@ namespace ScriptCanvas } else { - // we don't support this, yet, but visually we could - // we could support both things, technically...auto-generated inputs, and defaults on the non-connected - // execution thread, or whatever makes possible sense - // \todo send enough information to reveal the data path in the editor - + // This isn't supported visually, yet, but technically, it could be. + // One could connect both latent execution and immediate execution to the same code execution path, + // but only one uses connected output, and the other uses defaults. + // It would require us to change the visualization of the shared path, based on which parent was clicked on in the editor. const auto& targetNode = *execution->GetId().m_node; const auto& targetSlot = input; for (auto sourceNodeAndSlot : nodes) { AddError(nullptr, aznew ScopedDataConnectionEvent - (execution->GetNodeId() + ( execution->GetNodeId() , targetNode , targetSlot , *sourceNodeAndSlot.first , *sourceNodeAndSlot.second)); } + + return; } } + + // Check for known null reads + CheckForKnownNullDereference(execution, execution->GetInput(execution->GetInputCount() - 1), input); } bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution) @@ -4428,6 +4427,7 @@ namespace ScriptCanvas if (auto eventHandling = GetEBusEventHandling(node)) { auto variable = AZStd::make_shared(); + variable->m_isMember = true; variable->m_datum = Datum(eventHandling->m_handlerName); execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index 06854fdbfd..45e289739d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -207,8 +207,10 @@ namespace ScriptCanvas bool CheckCreateRoot(const Node& node); + void CheckForKnownNullDereference(ExecutionTreeConstPtr parent, const ExecutionInput& input, const Slot& inputSlot); + AZStd::string CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp index 1ac9303082..6ac80de542 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp @@ -27,7 +27,6 @@ #include #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp deleted file mode 100644 index b8eb5f5ad5..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "GrammarContext.h" - -namespace ScriptCanvas -{ - namespace Grammar - { - const SubgraphInterfaceSystem& Context::GetExecutionMapSystem() const - { - return m_executionMapSystem; - } - - SubgraphInterfaceSystem& Context::ModExecutionMapSystem() - { - return m_executionMapSystem; - } - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h deleted file mode 100644 index 7a9d2eaec9..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -#include - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context - { - public: - AZ_CLASS_ALLOCATOR(Context, AZ::SystemAllocator, 0); - - Context() = default; - ~Context() = default; - - const SubgraphInterfaceSystem& GetExecutionMapSystem() const; - SubgraphInterfaceSystem& ModExecutionMapSystem(); - - private: - SubgraphInterfaceSystem m_executionMapSystem; - - // put grammatical state globals in here, things that can be useful across several parses of graphs - }; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h deleted file mode 100644 index 1630d0b99e..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetGrammarContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - // add stuff here to speed up parsing across separate graphs - }; - - using EventBus = AZ::EBus; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index 0984440bf4..011dfeda97 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -354,9 +354,9 @@ namespace ScriptCanvas return GetRoot()->m_isPure; } - bool ExecutionTree::IsStart() const + bool ExecutionTree::IsStartCall() const { - return m_isStart; + return m_isStartCall; } void ExecutionTree::MarkDebugEmptyStatement() @@ -403,9 +403,9 @@ namespace ScriptCanvas root->m_isLatent = true; } - void ExecutionTree::MarkStart() + void ExecutionTree::MarkStartCall() { - m_isStart = true; + m_isStartCall = true; } ExecutionChild& ExecutionTree::ModChild(size_t index) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h index c86f445a68..80d602ad17 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h @@ -199,7 +199,7 @@ namespace ScriptCanvas bool IsPure() const; - bool IsStart() const; + bool IsStartCall() const; void MarkDebugEmptyStatement(); @@ -215,7 +215,7 @@ namespace ScriptCanvas void MarkRootLatent(); - void MarkStart(); + void MarkStartCall(); ExecutionChild& ModChild(size_t index); @@ -286,7 +286,7 @@ namespace ScriptCanvas bool m_isPure = false; - bool m_isStart = false; + bool m_isStartCall = false; bool m_hasExplicitUserOutCalls = false; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 32b5e5741f..4eafa82331 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -25,6 +25,7 @@ namespace MethodCPP Unnamed2, PluralizeResults, AddedPrettyNameFieldToSerialization, + StoreInputSlotIdsToSupportNullCheck, // add your version above Current, }; @@ -110,6 +111,37 @@ namespace ScriptCanvas { namespace Core { + bool Method::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, const Slot& inputSlot) const + { + if (m_method) + { + auto candidateID = inputSlot.GetId(); + auto slotIter = AZStd::find(m_inputSlots.begin(), m_inputSlots.end(), candidateID); + + if (slotIter != m_inputSlots.end()) + { + const size_t index = slotIter - m_inputSlots.begin(); + if (index < m_method->GetNumArguments()) + { + const auto* argument = m_method->GetArgument(index); + if (argument->m_traits & (AZ::BehaviorParameter::TR_REFERENCE | AZ::BehaviorParameter::TR_THIS_PTR)) + { + // references and this pointers cannot accept null input + return false; + } + + if (!(argument->m_traits & AZ::BehaviorParameter::TR_POINTER)) + { + // values cannot accept null input + return false; + } + } + } + } + + return true; + } + const AZ::BehaviorClass* Method::GetClass() const { return m_class; @@ -232,6 +264,11 @@ namespace ScriptCanvas if (addedSlot.IsValid()) { MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex); + m_inputSlots.push_back(addedSlot); + } + else + { + AZ_Warning("ScriptCanvas", false, "Failed to add method input slot to Method node: %s-%s", config.m_prettyClassName.c_str(), config.m_method.m_name.c_str()); } } } @@ -520,8 +557,8 @@ namespace ScriptCanvas if (m_method && m_method->HasResult()) { if (branchOnResultMethod.GetNumArguments() == 1 - && branchOnResultMethod.HasResult() - && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) + && branchOnResultMethod.HasResult() + && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) { AZ::Uuid methodResultType = m_method->GetResult()->m_typeId; AZ::Uuid branchOnResultMethodArgType = branchOnResultMethod.GetArgument(0)->m_typeId; @@ -797,6 +834,7 @@ namespace ScriptCanvas ->Field("className", &Method::m_className) ->Field("namespaces", &Method::m_namespaces) ->Field("resultSlotIDs", &Method::m_resultSlotIDs) + ->Field("inputSlots", &Method::m_inputSlots) ->Field("prettyClassName", &Method::m_classNamePretty) ; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index db34da040c..3dec8e3e72 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -45,6 +45,8 @@ namespace ScriptCanvas size_t GenerateFingerprint() const override; + bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const override; + bool GetBranchOnResultCheckName(AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; virtual bool GetCheckedOperationInfo(AZ::CheckedOperationInfo& checkedInfo, AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; @@ -149,8 +151,6 @@ namespace ScriptCanvas bool IsExpectingResult() const; - AZ_INLINE AZStd::vector& ModResultSlotIds() { return m_resultSlotIDs; } - virtual void OnInitializeOutputPost(const MethodOutputConfig&) {} virtual void OnInitializeOutputPre(MethodOutputConfig&) {} @@ -176,6 +176,7 @@ namespace ScriptCanvas NamespacePath m_namespaces; const AZ::BehaviorMethod* m_method = nullptr; const AZ::BehaviorClass* m_class = nullptr; + AZStd::vector m_inputSlots; AZStd::vector m_resultSlotIDs; AZStd::recursive_mutex m_mutex; // post-serialization bool m_warnOnMissingFunction = true; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h index 339c0fc3a1..928d1d7202 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h @@ -74,6 +74,7 @@ namespace ScriptCanvas constexpr const char* NotEnoughBranchesForReturn = "Not enough branches for defined out return values."; constexpr const char* NotEnoughInputForArithmeticOperator = "Not enough input for arithmetic operator"; constexpr const char* NullEntityInGraph = "Null entity pointer in graph"; + constexpr const char* NullInputKnown = "The input is known to be null, and the node does not accept it"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced = "ParseExecutionMultipleOutSyntaxSugar: child execution node was removed, and not replaced."; constexpr const char* ParseExecutionMultipleOutSyntaxSugarMismatchOutSize = "ParseExecutionMultipleOutSyntaxSugar: mismatch in connect nodes vs source slots size"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound = "ParseExecutionMultipleOutSyntaxSugar: non null child execution node"; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index 772fda4f7e..085a0928bc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -24,8 +24,6 @@ #include #include "GraphToLuaUtility.h" -#include "TranslationContext.h" -#include "TranslationContextBus.h" namespace GraphToLuaCpp { @@ -92,9 +90,7 @@ namespace ScriptCanvas { SystemRequestBus::BroadcastResult(m_systemConfiguration, &SystemRequests::GetSystemComponentConfiguration); MarkTranslationStart(); - RequestBus::BroadcastResult(m_context, &RequestTraits::GetTranslationContext); - AZ_Assert(m_context, "Nothing is possible without the context"); - + m_tableName = GraphToLuaCpp::FileNameToTableName(m_model.GetSource().m_name); m_tableName += m_configuration.m_suffix; @@ -138,12 +134,12 @@ namespace ScriptCanvas const AZStd::string& GraphToLua::FindAbbreviation(AZStd::string_view dependency) const { - return m_context->FindAbbreviation(dependency); + return m_context.FindAbbreviation(dependency); } const AZStd::string& GraphToLua::FindLibrary(AZStd::string_view dependency) const { - return m_context->FindLibrary(dependency); + return m_context.FindLibrary(dependency); } AZStd::string_view GraphToLua::GetOperatorString(Grammar::ExecutionTreeConstPtr execution) @@ -806,7 +802,7 @@ namespace ScriptCanvas m_dotLua.Write("("); - if (execution->IsStart() && execution->IsPure()) + if (execution == m_model.GetStart() && execution->IsPure()) { m_dotLua.Write(Grammar::k_executionStateVariableName); @@ -1589,8 +1585,10 @@ namespace ScriptCanvas break; } - // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables -// if (execution->IsStart() && execution->IsPure()) + // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables, which is a work-flow we may never want to support + // as it effectively duplicates the Component-Entity-System. Technically, if this functionality is desired, one could just add another script component + // with the additional graph... +// if (execution->IsStartCall() && execution->IsPure()) // { // WriteFunctionCallInputOfChildStart(execution); // } @@ -1944,7 +1942,7 @@ namespace ScriptCanvas { const auto requirement = ParseConstructionRequirement(variable); - if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStart())) + if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStartCall())) { m_dotLua.WriteLineIndented("local %s = %s", variable->m_name.data(), ToValueString(variable->m_datum, m_configuration).data()); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h index ba46b21c65..347cb764e9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h @@ -16,6 +16,7 @@ #include #include "GraphToX.h" +#include "TranslationContext.h" #include "TranslationResult.h" #include "TranslationUtilities.h" @@ -60,7 +61,7 @@ namespace ScriptCanvas RuntimeInputs m_runtimeInputs; BuildConfiguration m_executionConfig = BuildConfiguration::Release; FunctionBlockConfig m_functionBlockConfig = FunctionBlockConfig::Ignored; - const Context* m_context = nullptr; + Context m_context; AZStd::string m_tableName; Writer m_dotLua; SystemComponentConfiguration m_systemConfiguration; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h index ea49f90bde..40f04f2f47 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h @@ -10,7 +10,6 @@ #include #include #include "Translation.h" -#include "TranslationContextBus.h" namespace ScriptCanvas { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h deleted file mode 100644 index 0edac2afe3..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -#include "Translation.h" - -namespace ScriptCanvas -{ - namespace Translation - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetTranslationContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - }; - - using EventBus = AZ::EBus; - - } - -} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 40b5786303..17273b7ae0 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -101,7 +101,6 @@ set(FILES Include/ScriptCanvas/Translation/Translation.cpp Include/ScriptCanvas/Translation/TranslationContext.h Include/ScriptCanvas/Translation/TranslationContext.cpp - Include/ScriptCanvas/Translation/TranslationContextBus.h Include/ScriptCanvas/Translation/TranslationResult.h Include/ScriptCanvas/Translation/TranslationResult.cpp Include/ScriptCanvas/Translation/TranslationUtilities.h @@ -196,9 +195,6 @@ set(FILES Include/ScriptCanvas/Grammar/DebugMap.cpp Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp - Include/ScriptCanvas/Grammar/GrammarContext.h - Include/ScriptCanvas/Grammar/GrammarContext.cpp - Include/ScriptCanvas/Grammar/GrammarContextBus.h Include/ScriptCanvas/Grammar/ParsingMetaData.h Include/ScriptCanvas/Grammar/ParsingMetaData.cpp Include/ScriptCanvas/Grammar/ParsingUtilities.h diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas new file mode 100644 index 0000000000..4453617996 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp index 727f73be39..e54c83c5d3 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 107bb32cd6..db3d2223d6 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -85,6 +83,16 @@ public: } }; +TEST_F(ScriptCanvasTestFixture, ProveError) +{ + EXPECT_TRUE(false); +} + +TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) +{ + ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); +} + TEST_F(ScriptCanvasTestFixture, UseBehaviorContextClassConstant) { RunUnitTestGraph("LY_SC_UnitTest_UseBehaviorContextClassConstant"); diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp index 0733101743..8c4983da0f 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index 5fa2d6fd88..2f3c8d08be 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -185,7 +185,7 @@ void DebugComponent::DisplayEntityViewport(const AzFramework::ViewportInfo& view } } -void DebugComponent::DrawInstanceDebug(AzFramework::DebugDisplayRequests& debugDisplay) +void DebugComponent::DrawInstanceDebug([[maybe_unused]] AzFramework::DebugDisplayRequests& debugDisplay) { #if defined(VEG_PROFILE_ENABLED) AZStd::unordered_map areaDebugDisplayDataMap; diff --git a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp index e9b5514006..b1f26e2e2e 100644 --- a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp +++ b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp @@ -34,8 +34,8 @@ namespace WhiteBox AZ::Color, cl_whiteBoxVertexIndicatorColor, AZ::Color::CreateFromRgba(0, 0, 0, 102), nullptr, AZ::ConsoleFunctorFlags::Null, "The color of the vertex indicator"); - static const AZ::Crc32 HideEdge = AZ_CRC("com.amazon.action.whitebox.hide_edge", 0x6a60ae23); - static const AZ::Crc32 HideVertex = AZ_CRC("com.amazon.action.whitebox.hide_vertex", 0x4a4bd092); + static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x6a60ae23); + static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x4a4bd092); static const char* const HideEdgeTitle = "Hide Edge"; static const char* const HideEdgeDesc = "Hide the selected edge to merge the two connected polygons"; diff --git a/Registry/AssetProcessorPlatformConfig.setreg b/Registry/AssetProcessorPlatformConfig.setreg index 0e91bec8a7..26aa5b2663 100644 --- a/Registry/AssetProcessorPlatformConfig.setreg +++ b/Registry/AssetProcessorPlatformConfig.setreg @@ -76,7 +76,8 @@ "animsettings": "i_caf", "Animations/SkeletonList.xml": "i_caf", "cbc": "abc", - "fbx.assetinfo": "fbx" + "fbx.assetinfo": "fbx", + "stl.assetinfo": "stl" }, // ---- add any folders to scan here. The priority order is the order they appear here diff --git a/Templates/DefaultGem/Template/CMakeLists.txt b/Templates/DefaultGem/Template/CMakeLists.txt index d00a5f0128..5ea435a790 100644 --- a/Templates/DefaultGem/Template/CMakeLists.txt +++ b/Templates/DefaultGem/Template/CMakeLists.txt @@ -10,13 +10,7 @@ set(o3de_gem_json ${o3de_gem_path}/gem.json) o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name") o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path) -# Currently we are in the DefaultProjectSource folder: ${CMAKE_CURRENT_LIST_DIR} -# Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} -# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform -# in which case it will see if that platform is present here or in the restricted folder. -# i.e. It could here: DefaultProjectSource/Platform/ or -# //DefaultProjectSource -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) +ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${o3de_gem_restricted_path}" ${o3de_gem_path} ${o3de_gem_name}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # project cmake for this platform. diff --git a/Templates/DefaultProject/preview.png b/Templates/DefaultProject/preview.png new file mode 100644 index 0000000000..78a2a735d2 --- /dev/null +++ b/Templates/DefaultProject/preview.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ae503ec99c8358991dc3c6e50737844d3602b81a49abbbed7d697d7238547c0 +size 28026 diff --git a/Templates/MinimalProject/preview.png b/Templates/MinimalProject/preview.png new file mode 100644 index 0000000000..b94e84a348 --- /dev/null +++ b/Templates/MinimalProject/preview.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c14254e4c822fb50bfec42691c49f1089ab020a873c366f71168390d3705c6e +size 17522 diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index a7a5c99adf..5e2fdff8ea 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -42,5 +42,5 @@ ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-mac ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-mac TARGETS googletest PACKAGE_HASH cbf020d5ef976c5db8b6e894c6c63151ade85ed98e7c502729dd20172acae5a8) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-mac TARGETS GoogleBenchmark PACKAGE_HASH ad25de0146769c91e179953d845de2bec8ed4a691f973f47e3eb37639381f665) ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev1-mac TARGETS OpenSSL PACKAGE_HASH 28adc1c0616ac0482b2a9d7b4a3a3635a1020e87b163f8aba687c501cf35f96c) -ly_associate_package(PACKAGE_NAME qt-5.15.2-rev4-mac TARGETS Qt PACKAGE_HASH 08790d03a0e6ad808ad64cf25c3d75abd69a343f3d224fc39927e5c6e8738b98) +ly_associate_package(PACKAGE_NAME qt-5.15.2-rev5-mac TARGETS Qt PACKAGE_HASH 9d25918351898b308ded3e9e571fff6f26311b2071aeafd00dd5b249fdf53f7e) ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-mac TARGETS libsamplerate PACKAGE_HASH b912af40c0ac197af9c43d85004395ba92a6a859a24b7eacd920fed5854a97fe) diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake index b6daf8b6d7..40bf6ef541 100644 --- a/cmake/LYWrappers.cmake +++ b/cmake/LYWrappers.cmake @@ -380,12 +380,14 @@ function(ly_delayed_target_link_libraries) cmake_parse_arguments(ly_delayed_target_link_libraries "" "" "${visibilities}" ${delayed_link}) foreach(visibility ${visibilities}) - foreach(item ${ly_delayed_target_link_libraries_${visibility}}) + foreach(alias_item ${ly_delayed_target_link_libraries_${visibility}}) - if(TARGET ${item}) - get_target_property(item_type ${item} TYPE) + if(TARGET ${alias_item}) + get_target_property(item_type ${alias_item} TYPE) + ly_de_alias_target(${alias_item} item) else() unset(item_type) + set(item ${alias_item}) endif() if(item_type STREQUAL MODULE_LIBRARY) diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index 11541d395a..c51b39482f 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -29,7 +29,8 @@ function(o3de_restricted_id o3de_json_file restricted) ly_file_read(${o3de_json_file} json_data) string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted_name") if(json_error) - message(WARNING "Unable to read restricted from '${o3de_json_file}', error: ${json_error}") + # Restricted fields can never be a requirement so no warning is issued + return() endif() if(restricted_entry) set(${restricted} ${restricted_entry} PARENT_SCOPE) @@ -148,86 +149,89 @@ function(ly_get_absolute_pal_filename out_name in_name) set(full_name ${in_name}) if(${ARGC} GREATER 4) - # The user has supplied an object restricted path, the object path and the object name for consideration - set(object_restricted_path ${ARGV2}) - set(object_path ${ARGV3}) + # The object name is used to resolve ambiguities when a PAL directory is requested from + # two different external subdirectory root paths + # Such as if a PAL directory for two root object paths with same relative structure was requested to be Palified + # i.e /Platform//IO and /Platform//IO + # Normally the restricted PAL path for both gems would be "//IO". + # The object name can be used to make this path unique + # "///IO" for gem 1 and + # "///IO" for gem 2 set(object_name ${ARGV4}) - - # if the file is not in the object path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${object_path} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${object_path}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${object_path}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_1}/${object_name}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_2}/${object_name}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) - - elseif(${ARGC} GREATER 3) - # The user has supplied an object restricted path, the object path for consideration - set(object_restricted_path ${ARGV2}) - set(object_path ${ARGV3}) - - # if the file is not in the object path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${object_path} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${object_path}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${object_path}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) - - else() - # The user has not supplied any path so we must assume it is the o3de engine restricted and o3de engine path - # if the file is not in the o3de engine path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${LY_ROOT_FOLDER} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${LY_ROOT_FOLDER}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${LY_ROOT_FOLDER}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) endif() + + # The Default object path for path is the LY_ROOT_FOLDER + cmake_path(SET object_path NORMALIZE "${LY_ROOT_FOLDER}") + if(${ARGC} GREATER 3) + # The user has supplied an object restricted path, the object path for consideration + cmake_path(SET object_path NORMALIZE ${ARGV3}) + endif() + + # The Default restricted object path is the result of the read_engine_restricted_path function + cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") + if(${ARGC} GREATER 2) + # The user has supplied an object restricted path + cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + endif() + + # The input path must exist in order to form a PAL path + if (NOT EXISTS ${full_name}) + # if the file is not in the object path then we cannot determine a PAL file for it + cmake_path(IS_PREFIX object_path ${full_name} is_input_path_in_root) + if(is_input_path_in_root) + cmake_path(RELATIVE_PATH full_name BASE_DIRECTORY ${object_path} OUTPUT_VARIABLE relative_object_path) + cmake_path(SET current_object_path ${relative_object_path}) + + # Remove one path segment from the end of the current_object_path and prepend it to the list path_segments + cmake_path(GET current_object_path PARENT_PATH parent_path) + cmake_path(GET current_object_path FILENAME path_segment) + list(PREPEND path_segments_visited path_segment) + cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(SET current_object_path "${parent_path}") + + while(is_prev_path_segment) + # The Path is in a PAL structure + # Decompose the path into sections before "Platform" and after "Platform" + if(path_segment STREQUAL "Platform") + # The first path segment after the "/Platform/" + # is a potential platform name. Store it off for later checks + list(GET path_segments_visited 0 candidate_platform_name) + + # Store off all the path segments iterated from the end in the post-"Platform" path + cmake_path(APPEND post_platform_paths ${path_segments_visited}) + # The parent path is just the pre-"Platform" section of the path + cmake_path(SET pre_platform_paths "${parent_path}") + break() + endif() + + # Remove one path segment from the end of the current_object_path and prepend it to the list path_segments + cmake_path(GET current_object_path PARENT_PATH parent_path) + cmake_path(GET current_object_path FILENAME path_segment) + list(PREPEND path_segments_visited path_segment) + cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(SET current_object_path "${parent_path}") + endwhile() + + # Compose a candidate restricted path and examine if it exists + cmake_path(APPEND object_restricted_path ${pre_platform_paths} "Platform" ${post_platform_paths} + OUTPUT_VARIABLE candidate_PAL_path) + if(NOT EXISTS ${candidate_PAL_path}) + if("${candidate_platform_name}" IN_LIST PAL_RESTRICTED_PLATFORMS) + cmake_path(APPEND object_restricted_path ${candidate_platform_name} ${object_name} + ${pre_platform_paths} ${post_platform_paths} OUTPUT_VARIABLE candidate_PAL_path) + endif() + endif() + if(EXISTS ${candidate_PAL_path}) + cmake_path(SET full_name ${candidate_PAL_path}) + endif() + endif() + endif() + set(${out_name} ${full_name} PARENT_SCOPE) endfunction() function(ly_get_list_relative_pal_filename out_name in_name) ly_get_absolute_pal_filename(abs_name ${in_name} ${ARGN}) - file(RELATIVE_PATH relative_name ${CMAKE_CURRENT_LIST_DIR} ${abs_name}) + cmake_path(RELATIVE_PATH abs_name BASE_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE relative_name) set(${out_name} ${relative_name} PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index 734dd94203..31c8191a57 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -254,7 +254,8 @@ function(ly_delayed_generate_runtime_dependencies) # Generate the output file set(target_file_dir "$") - file(READ ${LY_RUNTIME_DEPENDENCIES_TEMPLATE} template_file) + set(target_file "$") + ly_file_read(${LY_RUNTIME_DEPENDENCIES_TEMPLATE} template_file) string(CONFIGURE "${LY_COPY_COMMANDS}" LY_COPY_COMMANDS @ONLY) string(CONFIGURE "${template_file}" configured_template_file @ONLY) file(GENERATE diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in index e2a85374b8..9d23a73a26 100644 --- a/cmake/Platform/Common/runtime_dependencies_common.cmake.in +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -13,6 +13,7 @@ function(ly_copy source_file target_directory) if(NOT ${same_location}) file(LOCK ${target_directory}/${target_filename}.lock GUARD FUNCTION TIMEOUT 300) if("${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") + message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) endif() endif() diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 92ad3514d4..9f9006c4c0 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -19,56 +19,96 @@ endfunction() include(BundleUtilities) cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of the LY_BUILD_FIXUP_BUNDLE expansion +cmake_policy(SET CMP0009 NEW) # do not traverse symlinks on GLOB_RECURSE set(anything_new FALSE) set(plugin_libs) set(plugin_dirs) +set(depends_on_python FALSE) + +find_program(LY_INSTALL_NAME_TOOL install_name_tool) +if (NOT LY_INSTALL_NAME_TOOL) + message(FATAL_ERROR "Unable to locate 'install_name_tool'") +endif() function(ly_copy source_file target_directory) get_filename_component(target_filename "${source_file}" NAME) - # If source_file is a Framework and target_directory is a bundle - if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") + # If target_directory is a bundle + if("${target_directory}" MATCHES "\\.app/Contents/MacOS") - if(NOT @LY_BUILD_FIXUP_BUNDLE@) - return() - endif() + set(target_is_bundle TRUE) + if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]") - # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks - string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") - get_filename_component(source_file_folder "${source_file}" DIRECTORY) + if(NOT @LY_BUILD_FIXUP_BUNDLE@) + return() + endif() + + # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks + string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") + get_filename_component(source_file_folder "${source_file}" DIRECTORY) + + # Python.framework produces a bug in BundleUtilities so it needs manual handling + # https://gitlab.kitware.com/cmake/cmake/-/issues/20165 + if("${source_file}" MATCHES "Python.framework") + # fixup the destination so it ends up in Contents/Frameworks + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/Frameworks" target_directory "${target_directory}") + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}/Python.framework") + set(target_filename Python.framework) + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + set(depends_on_python TRUE PARENT_SCOPE) + else() + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${source_file_folder}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + return() + endif() + + elseif("${source_file}" MATCHES "qt/plugins") + + if(NOT @LY_BUILD_FIXUP_BUNDLE@) + return() + endif() + + # fixup the destination so it ends up in Contents/Plugins + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/plugins" target_directory "${target_directory}") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + set(local_plugin_libs ${plugin_libs}) + list(APPEND local_plugin_libs "${target_directory}/${target_filename}") + set(plugin_libs ${local_plugin_libs} PARENT_SCOPE) + + elseif("${source_file}" MATCHES "qt/translations") + + return() # skip, is this used? - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${source_file_folder}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - return() + elseif("${source_file}" MATCHES ".dylib") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - elseif("${source_file}" MATCHES "qt/plugins" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - - if(NOT @LY_BUILD_FIXUP_BUNDLE@) - return() endif() - - # fixup the destination so it ends up in Contents/Plugins - string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/plugins" target_directory "${target_directory}") - - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${target_directory}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - set(local_plugin_libs ${plugin_libs}) - list(APPEND local_plugin_libs "${target_directory}/${target_filename}") - set(plugin_libs ${local_plugin_libs} PARENT_SCOPE) - - elseif("${source_file}" MATCHES "qt/translations" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - - return() # skip, is this used? - elseif("${source_file}" MATCHES ".dylib") + else() - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${target_directory}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + # target is not a bundle + set(target_is_bundle FALSE) + if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]") + + # fixup origin to copy the whole Framework folder + string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") + get_filename_component(target_filename "${source_file}" NAME) + + if("${source_file}" MATCHES "Python.framework") + set(depends_on_python TRUE PARENT_SCOPE) + endif() + + endif() endif() @@ -79,6 +119,11 @@ function(ly_copy source_file target_directory) endif() if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") + if(NOT target_is_bundle) + # if it is a bundle, there is no contention about the files in the destination, each bundle target will copy everything + # we dont want these files to invalidate the bundle and cause a new signature + file(LOCK ${target_directory}/${target_filename}.lock GUARD FUNCTION TIMEOUT 300) + endif() file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) file(TOUCH ${target_directory}/${target_filename}) set(anything_new TRUE PARENT_SCOPE) @@ -93,6 +138,7 @@ if(NOT @LY_BUILD_FIXUP_BUNDLE@) endif() if(@target_file_dir@ MATCHES ".app/Contents/MacOS") + string(REGEX REPLACE "(.*\\.app)/Contents/MacOS.*" "\\1" bundle_path "@target_file_dir@") set(fixup_timestamp_file "${bundle_path}.fixup.stamp") if(NOT anything_new) @@ -106,31 +152,44 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) list(APPEND fixup_bundle_ignore dxc-3.7) endif() - # Python.framework being copied by fixup_bundle - #if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) - # # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has - # # duplicated binaries between Versions/3.7 and Versions/Current. - # file(GLOB exe_files - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/distutils/command/*.exe - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip/_vendor/distlib/*.exe - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/setuptools/*.exe - # ) - # foreach(exe_file ${exe_files}) - # file(REMOVE ${exe_file}) - # endforeach() - # file(REMOVE_RECURSE - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Resources - # ${bundle_path}/Contents/Frameworks/Python.framework/Python - # ${bundle_path}/Contents/Frameworks/Python.framework/Resources/Python.app - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Python - # ) - # file(REMOVE_RECURSE ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current) - # execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current - # WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ - # ) - #endif() + # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has + # other issues that produce signature problems + if(depends_on_python) + message(STATUS "Fixing ${bundle_path}/Contents/Frameworks/Python.framework...") + list(APPEND fixup_bundle_ignore Python python3.7m python3.7) + file(REMOVE_RECURSE + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Headers + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/Python + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests + ${bundle_path}/Contents/Frameworks/Python.framework/Python + ${bundle_path}/Contents/Frameworks/Python.framework/Resources + ${bundle_path}/Contents/Frameworks/Python.framework/Headers + ) + file(GLOB_RECURSE exe_file_list "${bundle_path}/Contents/Frameworks/Python.framework/**/*.exe") + if(exe_file_list) + file(REMOVE_RECURSE ${exe_file_list}) + endif() + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink include/python3.7m Headers + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7 + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Python Python + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources Resources + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + file(CHMOD ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current/Python + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + endif() list(REMOVE_DUPLICATES plugin_libs) list(REMOVE_DUPLICATES plugin_dirs) fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}" IGNORE_ITEM ${fixup_bundle_ignore}) @@ -139,11 +198,27 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") # fixup bundle ends up removing the rpath of dxc (despite we exclude it) if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) - find_program(LY_INSTALL_NAME_TOOL install_name_tool) - if (NOT LY_INSTALL_NAME_TOOL) - message(FATAL_ERROR "Unable to locate 'install_name_tool'") - endif() execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) endif() + + # misplaced .DS_Store files can cause signing to fail + # Interrupted signatures can leave cstemp files behind that fail next signature + file(GLOB_RECURSE remove_file_list + "${bundle_path}/**/.DS_Store" + "${bundle_path/}**/*.cstemp" + ) + if(remove_file_list) + file(REMOVE_RECURSE ${remove_file_list}) + endif() + + endif() + +else() # Non-bundle case + + if(depends_on_python) + # RPATH fix python + execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -change @rpath/Python @rpath/Python.framework/Versions/Current/Python @target_file@) + endif() + endif() diff --git a/cmake/Platform/Windows/Packaging/Shortcuts.wxs b/cmake/Platform/Windows/Packaging/Shortcuts.wxs index 283a3c08ea..fefd15294a 100644 --- a/cmake/Platform/Windows/Packaging/Shortcuts.wxs +++ b/cmake/Platform/Windows/Packaging/Shortcuts.wxs @@ -26,10 +26,15 @@ - + + + Name="$(var.CPACK_PACKAGE_NAME) Project Manager" /> diff --git a/cmake/Platform/Windows/PackagingPostBuild.cmake b/cmake/Platform/Windows/PackagingPostBuild.cmake index 2d003d6062..70f8834207 100644 --- a/cmake/Platform/Windows/PackagingPostBuild.cmake +++ b/cmake/Platform/Windows/PackagingPostBuild.cmake @@ -105,39 +105,94 @@ file(TO_NATIVE_PATH "${_root_path}/python/python.cmd" _python_cmd) file(TO_NATIVE_PATH "${_root_path}/scripts/build/tools/upload_to_s3.py" _upload_script) file(TO_NATIVE_PATH "${_cpack_wix_out_dir}" _cpack_wix_out_dir) -# strip the scheme and extract the bucket/key prefix from the URL -string(REPLACE "s3://" "" _stripped_url ${CPACK_UPLOAD_URL}) -string(REPLACE "/" ";" _tokens ${_stripped_url}) +function(upload_to_s3 in_url in_local_path in_file_regex) -list(POP_FRONT _tokens _bucket) -string(JOIN "/" _prefix ${_tokens}) + # strip the scheme and extract the bucket/key prefix from the URL + string(REPLACE "s3://" "" _stripped_url ${in_url}) + string(REPLACE "/" ";" _tokens ${_stripped_url}) -set(_file_regex ".*(cab|exe|msi)$") -set(_extra_args [[{"ACL":"bucket-owner-full-control"}]]) + list(POP_FRONT _tokens _bucket) + string(JOIN "/" _prefix ${_tokens}) -set(_upload_command - ${_python_cmd} -s - -u ${_upload_script} - --base_dir ${_cpack_wix_out_dir} - --file_regex="${_file_regex}" - --bucket ${_bucket} - --key_prefix ${_prefix} - --extra_args ${_extra_args} -) + set(_extra_args [[{"ACL":"bucket-owner-full-control"}]]) -if(CPACK_AWS_PROFILE) - list(APPEND _upload_command --profile ${CPACK_AWS_PROFILE}) -endif() + set(_upload_command + ${_python_cmd} -s + -u ${_upload_script} + --base_dir ${in_local_path} + --file_regex="${in_file_regex}" + --bucket ${_bucket} + --key_prefix ${_prefix} + --extra_args ${_extra_args} + ) + + if(CPACK_AWS_PROFILE) + list(APPEND _upload_command --profile ${CPACK_AWS_PROFILE}) + endif() + + execute_process( + COMMAND ${_upload_command} + RESULT_VARIABLE _upload_result + OUTPUT_VARIABLE _upload_output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (NOT ${_upload_result} EQUAL 0) + message(FATAL_ERROR "An error occurred uploading to s3.\nOutput:\n${_upload_output}") + endif() +endfunction() message(STATUS "Uploading artifacts to ${CPACK_UPLOAD_URL}") -execute_process( - COMMAND ${_upload_command} - RESULT_VARIABLE _upload_result - ERROR_VARIABLE _upload_errors +upload_to_s3( + ${CPACK_UPLOAD_URL} + ${_cpack_wix_out_dir} + ".*(cab|exe|msi)$" ) +message(STATUS "Artifact uploading complete!") -if (${_upload_result} EQUAL 0) - message(STATUS "Artifact uploading complete!") -else() - message(FATAL_ERROR "An error occurred uploading artifacts. ${_upload_errors}") +# for auto tagged builds, we will also upload a second copy of just the boostrapper +# to a special "Latest" folder under the branch in place of the commit date/hash +if(CPACK_AUTO_GEN_TAG) + message(STATUS "Updating latest tagged build") + + # make sure we can extra the commit info from the URL first + string(REGEX MATCH "([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9a-zA-Z]+)" + _commit_info ${CPACK_UPLOAD_URL} + ) + if(NOT _commit_info) + message(FATAL_ERROR "Failed to extract the build tag") + endif() + + set(_temp_dir ${_cpack_wix_out_dir}/temp) + if(NOT EXISTS ${_temp_dir}) + file(MAKE_DIRECTORY ${_temp_dir}) + endif() + + # strip the version number form the exe name in the one uploaded to latest + string(TOLOWER "${CPACK_PACKAGE_NAME}_installer.exe" _non_versioned_exe) + set(_temp_exe_copy ${_temp_dir}/${_non_versioned_exe}) + + file(COPY ${_bootstrap_output_file} DESTINATION ${_temp_dir}) + file(RENAME "${_temp_dir}/${_bootstrap_filename}" ${_temp_exe_copy}) + + # include the commit info in a text file that will live next to the exe + set(_temp_info_file ${_temp_dir}/build_tag.txt) + file(WRITE ${_temp_info_file} ${_commit_info}) + + # update the URL and upload + string(REPLACE + ${_commit_info} "Latest" + _latest_upload_url ${CPACK_UPLOAD_URL} + ) + + upload_to_s3( + ${_latest_upload_url} + ${_temp_dir} + "(${_non_versioned_exe}|build_tag.txt)$" + ) + + # cleanup the temp files + file(REMOVE_RECURSE ${_temp_dir}) + + message(STATUS "Latest build update complete!") endif() diff --git a/cmake/SettingsRegistry.cmake b/cmake/SettingsRegistry.cmake index 0eae244c4f..934bae4e30 100644 --- a/cmake/SettingsRegistry.cmake +++ b/cmake/SettingsRegistry.cmake @@ -160,12 +160,6 @@ function(ly_delayed_generate_settings_registry) get_property(has_manually_added_dependencies TARGET ${gem_target} PROPERTY MANUALLY_ADDED_DEPENDENCIES SET) get_target_property(target_type ${gem_target} TYPE) - if (target_type STREQUAL "INTERFACE_LIBRARY" AND has_manually_added_dependencies) - # don't use interface libraries here, we only want ones which produce actual binaries unless the target - # is empty. We have still already recursed into their dependencies - they'll show up later. - # When the target has no dependencies however we want to add the gem root path to the generated setreg - continue() - endif() ly_get_gem_module_root(gem_module_root ${gem_target}) diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index ff4ccdc0a6..9d1d6e3122 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -253,7 +253,8 @@ def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: b logger.error( f'Attempting to register existing engine "{engine_name}" with a new path of {engine_path.as_posix()}.' f' The current path is {pathlib.Path(engines_path_json[engine_name]).as_posix()}.' - f' To force registration of a new engine path, specify the -f/--force option.') + f' To force registration of a new engine path, specify the -f/--force option.' + f'\nAlternatively the engine can be registered with a different name by changing the "engine_name" field in the engine.json.') return 1 engines_path_json[engine_name] = engine_path.as_posix() return 0 @@ -665,7 +666,7 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: result = 0 - for project in json_data['projects']: + for project in json_data.get('projects', []): if not validation.valid_o3de_project_json(pathlib.Path(project).resolve() / 'project.json'): logger.warn(f"Project path {project} is invalid.") # Attempt to unregister all invalid projects even if previous projects failed to unregister @@ -677,36 +678,36 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: def remove_invalid_o3de_objects() -> None: json_data = manifest.load_o3de_manifest() - for engine_object in json_data['engines']: - engine_path = engine_object['path'] + for engine_object in json_data.get('engines', []): + engine_path = engine_object.get('path', '') if not validation.valid_o3de_engine_json(pathlib.Path(engine_path).resolve() / 'engine.json'): logger.warn(f"Engine path {engine_path} is invalid.") register(engine_path=engine_path, remove=True) remove_invalid_o3de_projects() - for gem in json_data['gems']: + for gem in json_data.get('gems', []): if not validation.valid_o3de_gem_json(pathlib.Path(gem).resolve() / 'gem.json'): logger.warn(f"Gem path {gem} is invalid.") register(gem_path=gem, remove=True) - for external in json_data['external_subdirectories']: + for external in json_data.get('external_subdirectories', []): external = pathlib.Path(external).resolve() if not external.is_dir(): logger.warn(f"External subdirectory {external} is invalid.") register(engine_path=engine_path, external_subdir_path=external, remove=True) - for template in json_data['templates']: + for template in json_data.get('templates', []): if not validation.valid_o3de_template_json(pathlib.Path(template).resolve() / 'template.json'): logger.warn(f"Template path {template} is invalid.") register(template_path=template, remove=True) - for restricted in json_data['restricted']: + for restricted in json_data.get('restricted', []): if not validation.valid_o3de_restricted_json(pathlib.Path(restricted).resolve() / 'restricted.json'): logger.warn(f"Restricted path {restricted} is invalid.") register(restricted_path=restricted, remove=True) - default_engines_folder = pathlib.Path(json_data['default_engines_folder']).resolve() + default_engines_folder = pathlib.Path(json_data.get('default_engines_folder', manifest.get_o3de_engines_folder())).resolve() if not default_engines_folder.is_dir(): new_default_engines_folder = manifest.get_o3de_folder() / 'Engines' new_default_engines_folder.mkdir(parents=True, exist_ok=True) @@ -714,7 +715,7 @@ def remove_invalid_o3de_objects() -> None: f"Default engines folder {default_engines_folder} is invalid. Set default {new_default_engines_folder}") register(default_engines_folder=new_default_engines_folder.as_posix()) - default_projects_folder = pathlib.Path(json_data['default_projects_folder']).resolve() + default_projects_folder = pathlib.Path(json_data.get('default_projects_folder', manifest.get_o3de_projects_folder())).resolve() if not default_projects_folder.is_dir(): new_default_projects_folder = manifest.get_o3de_folder() / 'Projects' new_default_projects_folder.mkdir(parents=True, exist_ok=True) @@ -722,7 +723,7 @@ def remove_invalid_o3de_objects() -> None: f"Default projects folder {default_projects_folder} is invalid. Set default {new_default_projects_folder}") register(default_projects_folder=new_default_projects_folder.as_posix()) - default_gems_folder = pathlib.Path(json_data['default_gems_folder']).resolve() + default_gems_folder = pathlib.Path(json_data.get('default_gems_folder', manifest.get_o3de_gems_folder())).resolve() if not default_gems_folder.is_dir(): new_default_gems_folder = manifest.get_o3de_folder() / 'Gems' new_default_gems_folder.mkdir(parents=True, exist_ok=True) @@ -730,7 +731,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_gems_folder}") register(default_gems_folder=new_default_gems_folder.as_posix()) - default_templates_folder = pathlib.Path(json_data['default_templates_folder']).resolve() + default_templates_folder = pathlib.Path(json_data.get('default_templates_folder', manifest.get_o3de_templates_folder())).resolve() if not default_templates_folder.is_dir(): new_default_templates_folder = manifest.get_o3de_folder() / 'Templates' new_default_templates_folder.mkdir(parents=True, exist_ok=True) @@ -739,7 +740,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_templates_folder}") register(default_templates_folder=new_default_templates_folder.as_posix()) - default_restricted_folder = pathlib.Path(json_data['default_restricted_folder']).resolve() + default_restricted_folder = pathlib.Path(json_data.get('default_restricted_folder', manifest.get_o3de_restricted_folder())).resolve() if not default_restricted_folder.is_dir(): default_restricted_folder = manifest.get_o3de_folder() / 'Restricted' default_restricted_folder.mkdir(parents=True, exist_ok=True) @@ -748,7 +749,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {default_restricted_folder}") register(default_restricted_folder=default_restricted_folder.as_posix()) - default_third_party_folder = pathlib.Path(json_data['default_third_party_folder']).resolve() + default_third_party_folder = pathlib.Path(json_data.get('default_third_party_folder', manifest.get_o3de_third_party_folder())).resolve() if not default_third_party_folder.is_dir(): default_third_party_folder = manifest.get_o3de_folder() / '3rdParty' default_third_party_folder.mkdir(parents=True, exist_ok=True)