Comenzando la implementación final de permisos y depuración. Se sigue...

This commit is contained in:
2025-06-03 18:42:56 -03:00
parent 062cc05fd0
commit 8fb94f8cef
46 changed files with 711 additions and 493 deletions

View File

@@ -38,6 +38,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return null;
}
// GET: api/publicaciones
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<PublicacionDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
@@ -48,6 +49,26 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return Ok(publicaciones);
}
// GET: api/publicaciones/dropdown
[HttpGet("dropdown")]
[ProducesResponseType(typeof(IEnumerable<PublicacionDropdownDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
// No se verifica permiso DP001, solo requiere autenticación general ([Authorize] del controlador)
public async Task<IActionResult> GetPublicacionesForDropdown([FromQuery] bool soloHabilitadas = true)
{
try
{
var publicaciones = await _publicacionService.ObtenerParaDropdownAsync(soloHabilitadas);
return Ok(publicaciones);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener publicaciones para dropdown.");
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener publicaciones para selección.");
}
}
// GET: api/publicaciones/{id}
[HttpGet("{id:int}", Name = "GetPublicacionById")]
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
@@ -60,6 +81,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return Ok(publicacion);
}
// POST: api/publicaciones
[HttpPost]
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -77,6 +99,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return CreatedAtRoute("GetPublicacionById", new { id = dto.IdPublicacion }, dto);
}
// PUT: api/publicaciones/{id}
[HttpPut("{id:int}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -98,6 +121,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return NoContent();
}
// DELETE: api/publicaciones/{id}
[HttpDelete("{id:int}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -118,7 +142,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
return NoContent();
}
// Endpoint para obtener las configuraciones de días para una publicación
// Endpoint para obtener la configuración de días de publicación para una publicación específica
[HttpGet("{idPublicacion:int}/dias-semana")]
[ProducesResponseType(typeof(IEnumerable<PublicacionDiaSemanaDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]

View File

@@ -71,6 +71,25 @@ namespace GestionIntegral.Api.Controllers.Impresion
}
}
// GET: api/plantas/dropdown
[HttpGet("dropdown")]
[ProducesResponseType(typeof(IEnumerable<PlantaDropdownDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
// NO chequeo TienePermiso("IP001")(requiere autenticación)
public async Task<IActionResult> GetPlantasForDropdown()
{
try
{
var plantas = await _plantaService.ObtenerParaDropdownAsync();
return Ok(plantas);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener plantas para dropdown.");
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener plantas para selección.");
}
}
// GET: api/plantas/{id}
// Permiso: IP001 (Ver Plantas)
[HttpGet("{id:int}", Name = "GetPlantaById")]

View File

@@ -0,0 +1,9 @@
namespace GestionIntegral.Api.Dtos.Distribucion
{
public class PublicacionDropdownDto
{
public int IdPublicacion { get; set; }
public string Nombre { get; set; } = string.Empty;
public bool Habilitada { get; set; } // Simplificamos a bool, el backend manejará el default si es null
}
}

View File

@@ -0,0 +1,8 @@
namespace GestionIntegral.Api.Dtos.Impresion
{
public class PlantaDropdownDto
{
public int IdPlanta { get; set; }
public required string Nombre { get; set; }
}
}

View File

@@ -14,5 +14,6 @@ namespace GestionIntegral.Api.Services.Distribucion
Task<IEnumerable<PublicacionDiaSemanaDto>> ObtenerConfiguracionDiasAsync(int idPublicacion);
Task<IEnumerable<PublicacionDto>> ObtenerPublicacionesPorDiaSemanaAsync(byte diaSemana); // Devolvemos el DTO completo
Task<(bool Exito, string? Error)> ActualizarConfiguracionDiasAsync(int idPublicacion, UpdatePublicacionDiasSemanaRequestDto requestDto, int idUsuario);
Task<IEnumerable<PublicacionDropdownDto>> ObtenerParaDropdownAsync(bool soloHabilitadas = true);
}
}

View File

@@ -75,6 +75,22 @@ namespace GestionIntegral.Api.Services.Distribucion
return MapToDto(data);
}
public async Task<IEnumerable<PublicacionDropdownDto>> ObtenerParaDropdownAsync(bool soloHabilitadas = true)
{
var data = await _publicacionRepository.GetAllAsync(null, null, soloHabilitadas ? (bool?)true : null);
return data
.Where(p => p.Publicacion != null) // Asegurar que la publicación no sea null
.Select(d => new PublicacionDropdownDto
{
IdPublicacion = d.Publicacion!.IdPublicacion, // Usar ! si estás seguro que no es null después del Where
Nombre = d.Publicacion!.Nombre,
Habilitada = d.Publicacion!.Habilitada ?? true // Si necesitas filtrar por esto
})
.OrderBy(p => p.Nombre)
.ToList(); // O ToListAsync si el método del repo es async y devuelve IQueryable
}
public async Task<(PublicacionDto? Publicacion, string? Error)> CrearAsync(CreatePublicacionDto createDto, int idUsuario)
{
if (await _empresaRepository.GetByIdAsync(createDto.IdEmpresa) == null)

View File

@@ -11,5 +11,6 @@ namespace GestionIntegral.Api.Services.Impresion
Task<(PlantaDto? Planta, string? Error)> CrearAsync(CreatePlantaDto createDto, int idUsuario);
Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdatePlantaDto updateDto, int idUsuario);
Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario);
Task<IEnumerable<PlantaDropdownDto>> ObtenerParaDropdownAsync();
}
}

View File

@@ -114,8 +114,8 @@ namespace GestionIntegral.Api.Services.Impresion
};
using var connection = _connectionFactory.CreateConnection();
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
using var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
using var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
try
{
@@ -133,14 +133,14 @@ namespace GestionIntegral.Api.Services.Impresion
}
catch (KeyNotFoundException knfex) // Captura específica si el repo la lanza
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en ActualizarAsync Planta."); }
_logger.LogWarning(knfex, "Intento de actualizar Planta ID: {Id} no encontrada.", id);
return (false, "Planta no encontrada.");
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en ActualizarAsync Planta."); }
_logger.LogWarning(knfex, "Intento de actualizar Planta ID: {Id} no encontrada.", id);
return (false, "Planta no encontrada.");
}
catch (Exception ex)
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en ActualizarAsync Planta."); }
_logger.LogError(ex, "Error en transacción ActualizarAsync para Planta ID: {Id}", id);
_logger.LogError(ex, "Error en transacción ActualizarAsync para Planta ID: {Id}", id);
return (false, $"Error interno al actualizar la planta: {ex.Message}");
}
}
@@ -153,33 +153,42 @@ namespace GestionIntegral.Api.Services.Impresion
}
using var connection = _connectionFactory.CreateConnection();
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
using var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
try
{
var eliminado = await _plantaRepository.DeleteAsync(id, idUsuario, transaction);
if (!eliminado)
{
if (!eliminado)
{
throw new DataException("La operación de eliminación no afectó ninguna fila.");
}
}
transaction.Commit(); // <--- CORREGIDO: Commit síncrono
_logger.LogInformation("Planta ID {IdPlanta} eliminada exitosamente por Usuario ID {IdUsuario}.", id, idUsuario);
return (true, null);
}
catch (KeyNotFoundException knfex) // Captura específica si el repo la lanza
catch (KeyNotFoundException knfex) // Captura específica si el repo la lanza
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en EliminarAsync Planta."); }
_logger.LogWarning(knfex, "Intento de eliminar Planta ID: {Id} no encontrada.", id);
return (false, "Planta no encontrada.");
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en EliminarAsync Planta."); }
_logger.LogWarning(knfex, "Intento de eliminar Planta ID: {Id} no encontrada.", id);
return (false, "Planta no encontrada.");
}
catch (Exception ex)
{
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en EliminarAsync Planta."); }
_logger.LogError(ex, "Error en transacción EliminarAsync para Planta ID: {Id}", id);
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error adicional durante el rollback en EliminarAsync Planta."); }
_logger.LogError(ex, "Error en transacción EliminarAsync para Planta ID: {Id}", id);
return (false, $"Error interno al eliminar la planta: {ex.Message}");
}
}
public async Task<IEnumerable<PlantaDropdownDto>> ObtenerParaDropdownAsync()
{
var plantas = await _plantaRepository.GetAllAsync(null, null);
return plantas
.OrderBy(p => p.Nombre)
.Select(p => new PlantaDropdownDto { IdPlanta = p.IdPlanta, Nombre = p.Nombre })
.ToList();
}
}
}

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("GestionIntegral.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+99532b03f191d55f42e738a90b97f9f1e0dc1a9c")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+062cc05fd00a484e43f8b4ff022e53ac49670a78")]
[assembly: System.Reflection.AssemblyProductAttribute("GestionIntegral.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("GestionIntegral.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
{"GlobalPropertiesHash":"C9goqBDGh4B0L1HpPwpJHjfbRNoIuzqnU7zFMHk1LhM=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["V/5slELlkFDzZ8iiVKV8Jt0Ia8AL5AZxPCWo9apx5lQ=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","k3qzLxTWHeeJhAuWKMdta6j24bmJ9BMRMjuFEEVCRu0=","x/sHyso3gy4zVCu3ljpnTYCqu8IGZNRok1JoXiabIP8=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","hUWSz0FL2Jxxt3J4cPvysP9naCA2/Cxeo8sJx8s2hvs="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"C9goqBDGh4B0L1HpPwpJHjfbRNoIuzqnU7zFMHk1LhM=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["V/5slELlkFDzZ8iiVKV8Jt0Ia8AL5AZxPCWo9apx5lQ=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","k3qzLxTWHeeJhAuWKMdta6j24bmJ9BMRMjuFEEVCRu0=","x/sHyso3gy4zVCu3ljpnTYCqu8IGZNRok1JoXiabIP8=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","1I2C2FVhJyFRbvyuGXnropbTYN\u002BqpCoTcHfxWbfWF10="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@@ -1 +1 @@
{"GlobalPropertiesHash":"w3MBbMV9Msh0YEq9AW/8s16bzXJ93T9lMVXKPm/r6es=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["V/5slELlkFDzZ8iiVKV8Jt0Ia8AL5AZxPCWo9apx5lQ=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","k3qzLxTWHeeJhAuWKMdta6j24bmJ9BMRMjuFEEVCRu0=","x/sHyso3gy4zVCu3ljpnTYCqu8IGZNRok1JoXiabIP8=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","hUWSz0FL2Jxxt3J4cPvysP9naCA2/Cxeo8sJx8s2hvs="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"w3MBbMV9Msh0YEq9AW/8s16bzXJ93T9lMVXKPm/r6es=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["V/5slELlkFDzZ8iiVKV8Jt0Ia8AL5AZxPCWo9apx5lQ=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","k3qzLxTWHeeJhAuWKMdta6j24bmJ9BMRMjuFEEVCRu0=","x/sHyso3gy4zVCu3ljpnTYCqu8IGZNRok1JoXiabIP8=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","1I2C2FVhJyFRbvyuGXnropbTYN\u002BqpCoTcHfxWbfWF10="],"CachedAssets":{},"CachedCopyCandidates":{}}