From e88650f22c372d0077d4d896014acc886b9c26cf Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Mar 2021 23:49:02 +0100 Subject: [PATCH] Tiny coding style fixups --- ext/ghoul | 2 +- include/openspace/rendering/dashboardtextitem.h | 2 +- .../atmosphere/rendering/renderableatmosphere.cpp | 5 +++-- modules/base/dashboard/dashboarditemdate.cpp | 2 +- modules/base/dashboard/dashboarditemframerate.cpp | 6 ++++-- modules/base/rotation/fixedrotation.cpp | 2 +- modules/exoplanets/exoplanetsmodule_lua.inl | 3 ++- .../fieldlines/rendering/renderablefieldlines.cpp | 2 +- modules/globebrowsing/src/rawtiledatareader.cpp | 3 ++- modules/globebrowsing/src/renderableglobe.cpp | 2 +- modules/globebrowsing/src/ringscomponent.cpp | 10 +++++----- modules/globebrowsing/src/ringscomponent.h | 2 +- modules/globebrowsing/src/shadowcomponent.cpp | 2 +- modules/iswa/rendering/iswacygnet.cpp | 3 ++- modules/kameleon/ext/kameleon | 2 +- modules/space/rendering/renderablehabitablezone.h | 6 +++--- modules/space/rendering/renderablestars.cpp | 7 ++++--- modules/vislab/vislabmodule.cpp | 2 +- src/documentation/documentation.cpp | 15 --------------- src/documentation/verifier.cpp | 2 +- src/engine/configuration.cpp | 8 ++++---- src/engine/moduleengine.cpp | 1 - src/engine/openspaceengine_lua.inl | 3 +-- src/rendering/dashboarditem.cpp | 2 +- src/rendering/renderable.cpp | 2 +- src/util/spicemanager.cpp | 2 +- support/coding/check_style_guide.py | 14 +++++++++----- support/coding/codegen | 2 +- 28 files changed, 54 insertions(+), 60 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 1ce3299b7e..9cc4945a56 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 1ce3299b7e5e835e52d1758406727d02b080916b +Subproject commit 9cc4945a561dbea243ede04f23b14340fa7d9c8c diff --git a/include/openspace/rendering/dashboardtextitem.h b/include/openspace/rendering/dashboardtextitem.h index 5dbeb00de9..d3b0e20a79 100644 --- a/include/openspace/rendering/dashboardtextitem.h +++ b/include/openspace/rendering/dashboardtextitem.h @@ -53,4 +53,4 @@ protected: } // openspace -#endif // __OPENSPACE_CORE___DASHBOARDITEM___H__ +#endif // __OPENSPACE_CORE___DASHBOARDTEXTITEM___H__ diff --git a/modules/atmosphere/rendering/renderableatmosphere.cpp b/modules/atmosphere/rendering/renderableatmosphere.cpp index 4859a00628..a2ca9476bf 100644 --- a/modules/atmosphere/rendering/renderableatmosphere.cpp +++ b/modules/atmosphere/rendering/renderableatmosphere.cpp @@ -179,7 +179,8 @@ namespace { // A list of objects that cast light on this atmosphere std::vector casters; }; - // Declares shadow groups, meaning which nodes are considered in shadow calculations + // Declares shadow groups, meaning which nodes are considered in shadow + // calculations std::optional shadowGroup; // [[codegen::verbatim(AtmosphereHeightInfo.description)]] @@ -360,7 +361,7 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary) _mieScatteringExtinctionPropCoefficient.onChange(updateWithCalculation); addProperty(_mieScatteringExtinctionPropCoefficient); - + if (p.debug.has_value()) { _preCalculatedTexturesScale = p.debug->preCalculatedTextureScale.value_or(_preCalculatedTexturesScale); diff --git a/modules/base/dashboard/dashboarditemdate.cpp b/modules/base/dashboard/dashboarditemdate.cpp index 87dc11ac6c..3a1a611f6d 100644 --- a/modules/base/dashboard/dashboarditemdate.cpp +++ b/modules/base/dashboard/dashboarditemdate.cpp @@ -55,7 +55,7 @@ namespace { struct [[codegen::Dictionary(DashboardItemDate)]] Parameters { // [[codegen::verbatim(FormatStringInfo.description)]] std::optional formatString; - + // [[codegen::verbatim(TimeFormatInfo.description)]] std::optional timeFormat; }; diff --git a/modules/base/dashboard/dashboarditemframerate.cpp b/modules/base/dashboard/dashboarditemframerate.cpp index 9405cac2c6..f16db9e6fb 100644 --- a/modules/base/dashboard/dashboarditemframerate.cpp +++ b/modules/base/dashboard/dashboarditemframerate.cpp @@ -132,7 +132,8 @@ namespace { DtAvg [[codegen::key("Average Deltatime")]], DtExtremes [[codegen::key("Deltatime extremes")]], DtStandardDeviation [[codegen::key("Deltatime standard deviation")]], - DtCoefficientOfVariation [[codegen::key("Deltatime coefficient of variation")]], + DtCoefficientOfVariation + [[codegen::key("Deltatime coefficient of variation")]], FPS [[codegen::key("Frames per second")]], FPSAvg [[codegen::key("Average frames per second")]] }; @@ -187,7 +188,8 @@ DashboardItemFramerate::DashboardItemFramerate(const ghoul::Dictionary& dictiona _frametimeType = static_cast(FrametimeType::DtStandardDeviation); break; case Parameters::Type::DtCoefficientOfVariation: - _frametimeType = static_cast(FrametimeType::DtCoefficientOfVariation); + _frametimeType = + static_cast(FrametimeType::DtCoefficientOfVariation); break; case Parameters::Type::FPS: _frametimeType = static_cast(FrametimeType::FPS); diff --git a/modules/base/rotation/fixedrotation.cpp b/modules/base/rotation/fixedrotation.cpp index 5d0d864ad0..c89e4dc489 100644 --- a/modules/base/rotation/fixedrotation.cpp +++ b/modules/base/rotation/fixedrotation.cpp @@ -185,7 +185,7 @@ namespace { struct [[codegen::Dictionary(FixedRotation)]] Parameters { // This value specifies the direction of the new X axis. If this value is not // specified, it will be computed by completing a right handed coordinate system - // from the Y and Z axis, which must be specified instead. If this value is a + // from the Y and Z axis, which must be specified instead. If this value is a // string, it is interpreted as the identifier of another scenegraph node. If this // value is a 3-vector, it is interpreted as a direction vector std::optional> xAxis; diff --git a/modules/exoplanets/exoplanetsmodule_lua.inl b/modules/exoplanets/exoplanetsmodule_lua.inl index 26d40cde45..5843cec267 100644 --- a/modules/exoplanets/exoplanetsmodule_lua.inl +++ b/modules/exoplanets/exoplanetsmodule_lua.inl @@ -56,7 +56,8 @@ namespace openspace::exoplanets::luascriptfunctions { constexpr const float AU = static_cast(distanceconstants::AstronomicalUnit); constexpr const float SolarRadius = static_cast(distanceconstants::SolarRadius); -constexpr const float JupiterRadius = static_cast(distanceconstants::JupiterRadius); +constexpr const float JupiterRadius = + static_cast(distanceconstants::JupiterRadius); ExoplanetSystem findExoplanetSystemInData(std::string_view starName) { const ExoplanetsModule* module = global::moduleEngine->module(); diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index 78a3e8dd51..e71c1e4bb3 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -126,7 +126,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) else { _vectorFieldInfo = dictionary.value(KeyVectorField); } - + if (!dictionary.hasValue(KeyFieldlines)) { LERROR(fmt::format("Renderable does not contain a key for '{}'", KeyFieldlines)); } diff --git a/modules/globebrowsing/src/rawtiledatareader.cpp b/modules/globebrowsing/src/rawtiledatareader.cpp index 1b5005585c..81254ff64d 100644 --- a/modules/globebrowsing/src/rawtiledatareader.cpp +++ b/modules/globebrowsing/src/rawtiledatareader.cpp @@ -949,7 +949,8 @@ TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile, bool allIsMissing = true; for (int y = 0; y < region.numPixels.y; ++y) { - const size_t yi = (static_cast(region.numPixels.y) - 1 - y) * bytesPerLine; + const size_t yi = + (static_cast(region.numPixels.y) - 1 - y) * bytesPerLine; size_t i = 0; for (int x = 0; x < region.numPixels.x; ++x) { for (size_t raster = 0; raster < _initData.nRasters; ++raster) { diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 85d23a654c..d2581bafdb 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -1487,7 +1487,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d program.setUniform("shadowMapTexture", shadowMapUnit); program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage); - } + } else if (_generalProperties.shadowMapping) { shadowMapUnit.activate(); // JCC: Avoiding a to recompiling the shaders or having more than one diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 418a96461b..144a058468 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -296,7 +296,7 @@ void RingsComponent::initialize() { addProperty(_texturePath); _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); } - + if (_ringsDictionary.hasKey(TextureFwrdInfo.identifier)) { _textureFwrdPath = absPath( _ringsDictionary.value(TextureFwrdInfo.identifier) @@ -306,7 +306,7 @@ void RingsComponent::initialize() { addProperty(_textureFwrdPath); _textureFileForwards->setCallback([&](const File&) { _textureIsDirty = true; }); } - + if (_ringsDictionary.hasKey(TextureBckwrdInfo.identifier)) { _textureBckwrdPath = absPath( _ringsDictionary.value(TextureBckwrdInfo.identifier) @@ -476,7 +476,7 @@ void RingsComponent::draw(const RenderData& data, _shader->setUniform(_uniformCacheAdvancedRings.colorFilterValue, _colorFilter); _shader->setUniform(_uniformCacheAdvancedRings.nightFactor, _nightFactor); _shader->setUniform(_uniformCacheAdvancedRings.sunPosition, _sunPosition); - + const glm::dmat4 inverseModelTransform = glm::inverse(modelTransform); glm::vec3 sunPositionObjectSpace = glm::normalize( @@ -614,7 +614,7 @@ void RingsComponent::draw(const RenderData& data, else { _texture->bind(); } - + _geometryOnlyShader->setUniform(_geomUniformCache.ringTexture, ringTextureUnit); } @@ -673,7 +673,7 @@ void RingsComponent::loadTexture() { using namespace ghoul::opengl; if (!_texturePath.value().empty()) { - + std::unique_ptr texture = TextureReader::ref().loadTexture( absPath(_texturePath) ); diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index 661096d3b7..a11ef59b18 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -98,7 +98,7 @@ private: ) _uniformCache; UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor, sunPosition, sunPositionObj, camPositionObj, ringTextureFwrd, ringTextureBckwrd, - ringTextureUnlit, ringTextureColor, ringTextureTransparency, shadowMatrix, + ringTextureUnlit, ringTextureColor, ringTextureTransparency, shadowMatrix, shadowMapTexture, zFightingPercentage ) _uniformCacheAdvancedRings; UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index ab237291c4..0655da2bde 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -323,7 +323,7 @@ RenderData ShadowComponent::begin(const RenderData& data) { // Saves current state glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_currentFBO); global::renderEngine->openglStateCache().viewport(_mViewport); - + glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; glDrawBuffers(3, drawBuffers); diff --git a/modules/iswa/rendering/iswacygnet.cpp b/modules/iswa/rendering/iswacygnet.cpp index 267f00ac53..944e309d26 100644 --- a/modules/iswa/rendering/iswacygnet.cpp +++ b/modules/iswa/rendering/iswacygnet.cpp @@ -184,7 +184,8 @@ void IswaCygnet::render(const RenderData& data, RendererTasks&) { _data.spatialScale.x * _data.offset, _data.spatialScale.w ); - glm::vec3 position = glm::vec3(pposition) * static_cast(pow(10.f, pposition.w)); + glm::vec3 position = + glm::vec3(pposition) * static_cast(pow(10.f, pposition.w)); // Activate shader _shader->activate(); diff --git a/modules/kameleon/ext/kameleon b/modules/kameleon/ext/kameleon index 8a5e966659..606edb945b 160000 --- a/modules/kameleon/ext/kameleon +++ b/modules/kameleon/ext/kameleon @@ -1 +1 @@ -Subproject commit 8a5e9666599e9578d50bf3801dd07a9edf95ccdb +Subproject commit 606edb945b62d0151f20270ddb2db4a9f558aaa1 diff --git a/modules/space/rendering/renderablehabitablezone.h b/modules/space/rendering/renderablehabitablezone.h index 6aa5d7f31b..75c921ee1a 100644 --- a/modules/space/rendering/renderablehabitablezone.h +++ b/modules/space/rendering/renderablehabitablezone.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_MODULE_EXOPLANETS___RENDERABLEHABITABLEZONE___H__ -#define __OPENSPACE_MODULE_EXOPLANETS___RENDERABLEHABITABLEZONE___H__ +#ifndef __OPENSPACE_MODULE_SPACE___RENDERABLEHABITABLEZONE___H__ +#define __OPENSPACE_MODULE_SPACE___RENDERABLEHABITABLEZONE___H__ #include #include @@ -72,4 +72,4 @@ private: } // namespace openspace -#endif // __OPENSPACE_MODULE_EXOPLANETS___RENDERABLEHABITABLEZONE___H__ +#endif // __OPENSPACE_MODULE_SPACE___RENDERABLEHABITABLEZONE___H__ diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index a1b1879f14..17d576693e 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -307,7 +307,8 @@ namespace { }; struct [[codegen::Dictionary(RenderableStars)]] Parameters { - // The path to the SPECK file containing information about the stars being rendered + // The path to the SPECK file containing information about the stars being + // rendered std::filesystem::path speckFile [[codegen::key("File")]]; // [[codegen::verbatim(ColorTextureInfo.description)]] @@ -336,8 +337,8 @@ namespace { // loading. This can be used to trim the dataset's automatic value range std::optional staticFilter; - // This is the value that is used to replace statically filtered values. Setting this - // value only makes sense if 'StaticFilter' is 'true', as well + // This is the value that is used to replace statically filtered values. Setting + // this value only makes sense if 'StaticFilter' is 'true', as well std::optional staticFilterReplacement; // [[codegen::verbatim(MagnitudeExponentInfo.description)]] diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp index 9546cc9704..bd97596c70 100644 --- a/modules/vislab/vislabmodule.cpp +++ b/modules/vislab/vislabmodule.cpp @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2020 * + * Copyright (c) 2014-2021 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * diff --git a/src/documentation/documentation.cpp b/src/documentation/documentation.cpp index 3c31287910..96a907209b 100644 --- a/src/documentation/documentation.cpp +++ b/src/documentation/documentation.cpp @@ -140,21 +140,6 @@ namespace openspace::documentation { const std::string DocumentationEntry::Wildcard = "*"; -//std::string concatenate(const std::vector& offenses) { -// std::string result = "Error in specification ("; -// for (const TestResult::Offense& o : offenses) { -// if (o.explanation.empty()) { -// result += fmt::format("{} ({}), ", o.offender, ghoul::to_string(o.reason)); -// } -// else { -// result += fmt::format("{} ({}: {}), ", o.offender, ghoul::to_string(o.reason), o.explanation); -// } -// } -// result.pop_back(); -// result.back() = ')'; -// return result; -//} - SpecificationError::SpecificationError(TestResult res, std::string comp) : ghoul::RuntimeError("Error in specification", std::move(comp)) , result(std::move(res)) diff --git a/src/documentation/verifier.cpp b/src/documentation/verifier.cpp index 4b2b909417..223de8bd57 100644 --- a/src/documentation/verifier.cpp +++ b/src/documentation/verifier.cpp @@ -312,7 +312,7 @@ TestResult Color4Verifier::operator()(const ghoul::Dictionary& dictionary, res.success = false; res.offenses.push_back({ key + ".a", TestResult::Offense::Reason::Verification }); } - + return res; } diff --git a/src/engine/configuration.cpp b/src/engine/configuration.cpp index ee4b6b7f07..f063bded20 100644 --- a/src/engine/configuration.cpp +++ b/src/engine/configuration.cpp @@ -60,7 +60,7 @@ namespace { std::optional> globalCustomizationScripts; // A list of paths that are automatically registered with the file system. If a - // key X is used in the table, it is then useable by referencing ${X} in all other + // key X is used in the table, it is then useable by referencing ${X} in all other // configuration files or scripts std::map paths; @@ -277,7 +277,7 @@ namespace { // errors easier. This defaults to 'false' std::optional checkOpenGLState; - // Determines whether each OpenGL call that happens should be logged using the + // Determines whether each OpenGL call that happens should be logged using the // 'TRACE' loglevel. This will bring the rendering to a crawl but provides useful // debugging features for the order in which OpenGL calls occur. This defaults to // 'false' @@ -312,7 +312,7 @@ namespace { // bar that gives an estimate of the loading progression std::optional showProgressbar; }; - // Values in this table describe the behavior of the loading screen that is + // Values in this table describe the behavior of the loading screen that is // displayed while the scene graph is created and initialized std::optional loadingScreen; @@ -458,7 +458,7 @@ void parseLuaState(Configuration& configuration) { } } } - + if (p.documentation.has_value()) { c.documentation.path = p.documentation->path.value_or(c.documentation.path); } diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index 05d98a3a04..e2e8836265 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -63,7 +63,6 @@ void ModuleEngine::initialize( m->initialize(configuration); } catch (const documentation::SpecificationError& e) { - //LFATALC(e.component, e.message); for (const documentation::TestResult::Offense& o : e.result.offenses) { LERRORC(e.component, o.offender + ": " + ghoul::to_string(o.reason)); } diff --git a/src/engine/openspaceengine_lua.inl b/src/engine/openspaceengine_lua.inl index 62a99f114e..d5881b8ada 100644 --- a/src/engine/openspaceengine_lua.inl +++ b/src/engine/openspaceengine_lua.inl @@ -306,11 +306,10 @@ int createSingleColorImage(lua_State* L) { // @TODO (emmbr 2020-12-18) Verify that the input dictionary is a vec3 // Would like to clean this up with a more direct use of the Verifier in the future - using namespace openspace::documentation; const std::string& key = "color"; ghoul::Dictionary colorDict; colorDict.setValue(key, d); - TestResult res = Color3Verifier()(colorDict, key); + documentation::TestResult res = documentation::Color3Verifier()(colorDict, key); if (!res.success) { return ghoul::lua::luaError( diff --git a/src/rendering/dashboarditem.cpp b/src/rendering/dashboarditem.cpp index a0f907f11b..d0f7e6ff39 100644 --- a/src/rendering/dashboarditem.cpp +++ b/src/rendering/dashboarditem.cpp @@ -89,7 +89,7 @@ DashboardItem::DashboardItem(const ghoul::Dictionary& dictionary) , _isEnabled(EnabledInfo, true) { const Parameters p = codegen::bake(dictionary); - + setIdentifier(p.identifier); if (p.guiName.has_value()) { setGuiName(*p.guiName); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 9fa0d27259..ffc5ceef16 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -129,7 +129,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) registerUpdateRenderBinFromOpacity(); const Parameters p = codegen::bake(dictionary); - + if (p.tag.has_value()) { if (std::holds_alternative(*p.tag)) { if (!std::get(*p.tag).empty()) { diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index f3c68adc56..1b22158f2c 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -586,7 +586,7 @@ std::string SpiceManager::dateFromEphemerisTime(double ephemerisTime, const char ephemerisTime, format )); } - + return std::string(Buffer); } diff --git a/support/coding/check_style_guide.py b/support/coding/check_style_guide.py index 8b23b4027f..ce60631737 100644 --- a/support/coding/check_style_guide.py +++ b/support/coding/check_style_guide.py @@ -3,7 +3,7 @@ """ OpenSpace -Copyright (c) 2014-2020 +Copyright (c) 2014-2021 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software @@ -59,7 +59,7 @@ import os import re import sys -current_year = '2020' +current_year = '2021' is_strict_mode = False is_silent_mode = False @@ -659,19 +659,23 @@ if not is_silent_mode: check_files( [basePath + 'src/**/*.cpp'], - [], + [basePath + 'src/**/*_codegen.cpp'], 'openspace_core', check_source_file ) check_files( [basePath + 'apps/**/*.cpp'], - [basePath + 'apps/**/ext/**/*.cpp'], + [basePath + 'apps/**/ext/**/*.cpp', basePath + 'apps/**/*_codegen.cpp'], 'openspace_app', check_source_file ) check_files( [basePath + 'modules/**/*.cpp'], - [basePath + 'modules/**/ext/**/*.cpp', basePath + 'modules/**/node_modules/**/*.cpp'], + [ + basePath + 'modules/**/ext/**/*.cpp', + basePath + 'modules/**/node_modules/**/*.cpp', + basePath + 'modules/**/*_codegen.cpp' + ], 'openspace_module', check_source_file ) diff --git a/support/coding/codegen b/support/coding/codegen index b3c0a745fa..1aac589ded 160000 --- a/support/coding/codegen +++ b/support/coding/codegen @@ -1 +1 @@ -Subproject commit b3c0a745fa68e5f762de8a06732038e3a6fd5e02 +Subproject commit 1aac589ded45ff416cc7f8673fcfd37095819bc2