From a6f1fdaa27036e445aed086a45732034e257aa71 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 31 Oct 2024 16:16:09 -0600 Subject: [PATCH 1/2] add PRAS as submodule --- src/PRAS/CapacityCredit/CapacityCredit.jl | 18 + .../CapacityCredit/CapacityCreditResult.jl | 26 ++ src/PRAS/CapacityCredit/EFC.jl | 189 ++++++++ src/PRAS/CapacityCredit/ELCC.jl | 138 ++++++ src/PRAS/CapacityCredit/utils.jl | 45 ++ src/PRAS/PRAS.jl | 13 + src/PRAS/PRASBase/PRASBase.jl | 43 ++ src/PRAS/PRASBase/SystemModel.jl | 156 +++++++ src/PRAS/PRASBase/assets.jl | 441 ++++++++++++++++++ src/PRAS/PRASBase/collections.jl | 59 +++ src/PRAS/PRASBase/read.jl | 292 ++++++++++++ src/PRAS/PRASBase/rts.pras | Bin 0 -> 979488 bytes src/PRAS/PRASBase/toymodel.pras | Bin 0 -> 17368 bytes src/PRAS/PRASBase/units.jl | 116 +++++ src/PRAS/PRASBase/utils.jl | 30 ++ src/PRAS/PRASBase/write.jl | 318 +++++++++++++ src/PRAS/ResourceAdequacy/ResourceAdequacy.jl | 60 +++ src/PRAS/ResourceAdequacy/metrics.jl | 114 +++++ .../ResourceAdequacy/results/availability.jl | 96 ++++ src/PRAS/ResourceAdequacy/results/energy.jl | 127 +++++ src/PRAS/ResourceAdequacy/results/flow.jl | 71 +++ src/PRAS/ResourceAdequacy/results/results.jl | 39 ++ .../ResourceAdequacy/results/shortfall.jl | 257 ++++++++++ src/PRAS/ResourceAdequacy/results/surplus.jl | 66 +++ .../ResourceAdequacy/results/utilization.jl | 69 +++ .../simulations/convolution/Convolution.jl | 89 ++++ .../simulations/convolution/conv.jl | 152 ++++++ .../convolution/result_shortfall.jl | 55 +++ .../simulations/convolution/result_surplus.jl | 43 ++ .../sequentialmontecarlo/DispatchProblem.jl | 422 +++++++++++++++++ .../SequentialMonteCarlo.jl | 170 +++++++ .../sequentialmontecarlo/SystemState.jl | 45 ++ .../result_availability.jl | 219 +++++++++ .../sequentialmontecarlo/result_energy.jl | 273 +++++++++++ .../sequentialmontecarlo/result_flow.jl | 148 ++++++ .../sequentialmontecarlo/result_shortfall.jl | 230 +++++++++ .../sequentialmontecarlo/result_surplus.jl | 177 +++++++ .../result_utilization.jl | 173 +++++++ .../simulations/sequentialmontecarlo/utils.jl | 178 +++++++ .../simulations/simulations.jl | 4 + src/PRAS/ResourceAdequacy/utils.jl | 54 +++ 41 files changed, 5215 insertions(+) create mode 100644 src/PRAS/CapacityCredit/CapacityCredit.jl create mode 100644 src/PRAS/CapacityCredit/CapacityCreditResult.jl create mode 100644 src/PRAS/CapacityCredit/EFC.jl create mode 100644 src/PRAS/CapacityCredit/ELCC.jl create mode 100644 src/PRAS/CapacityCredit/utils.jl create mode 100644 src/PRAS/PRAS.jl create mode 100644 src/PRAS/PRASBase/PRASBase.jl create mode 100644 src/PRAS/PRASBase/SystemModel.jl create mode 100644 src/PRAS/PRASBase/assets.jl create mode 100644 src/PRAS/PRASBase/collections.jl create mode 100644 src/PRAS/PRASBase/read.jl create mode 100644 src/PRAS/PRASBase/rts.pras create mode 100644 src/PRAS/PRASBase/toymodel.pras create mode 100644 src/PRAS/PRASBase/units.jl create mode 100644 src/PRAS/PRASBase/utils.jl create mode 100644 src/PRAS/PRASBase/write.jl create mode 100644 src/PRAS/ResourceAdequacy/ResourceAdequacy.jl create mode 100644 src/PRAS/ResourceAdequacy/metrics.jl create mode 100644 src/PRAS/ResourceAdequacy/results/availability.jl create mode 100644 src/PRAS/ResourceAdequacy/results/energy.jl create mode 100644 src/PRAS/ResourceAdequacy/results/flow.jl create mode 100644 src/PRAS/ResourceAdequacy/results/results.jl create mode 100644 src/PRAS/ResourceAdequacy/results/shortfall.jl create mode 100644 src/PRAS/ResourceAdequacy/results/surplus.jl create mode 100644 src/PRAS/ResourceAdequacy/results/utilization.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl create mode 100644 src/PRAS/ResourceAdequacy/simulations/simulations.jl create mode 100644 src/PRAS/ResourceAdequacy/utils.jl diff --git a/src/PRAS/CapacityCredit/CapacityCredit.jl b/src/PRAS/CapacityCredit/CapacityCredit.jl new file mode 100644 index 0000000..4942645 --- /dev/null +++ b/src/PRAS/CapacityCredit/CapacityCredit.jl @@ -0,0 +1,18 @@ +@reexport module CapacityCredit + +import Base: minimum, maximum, extrema +import Distributions: ccdf, Normal +import ..PRASBase: Generators, PowerUnit, Regions, SystemModel, unitsymbol +import ..ResourceAdequacy: assess, ReliabilityMetric, Result, Shortfall, + SimulationSpec, stderror, val + +export EFC, ELCC + +abstract type CapacityValuationMethod{M<:ReliabilityMetric} end + +include("utils.jl") +include("CapacityCreditResult.jl") +include("EFC.jl") +include("ELCC.jl") + +end diff --git a/src/PRAS/CapacityCredit/CapacityCreditResult.jl b/src/PRAS/CapacityCredit/CapacityCreditResult.jl new file mode 100644 index 0000000..aeeec9b --- /dev/null +++ b/src/PRAS/CapacityCredit/CapacityCreditResult.jl @@ -0,0 +1,26 @@ +struct CapacityCreditResult{ + S <: CapacityValuationMethod, M <: ReliabilityMetric, P <: PowerUnit} + + target_metric::M + lowerbound::Int + upperbound::Int + bound_capacities::Vector{Int} + bound_metrics::Vector{M} + + function CapacityCreditResult{S,M,P}( + target_metric::M, lowerbound::Int, upperbound::Int, + bound_capacities::Vector{Int}, bound_metrics::Vector{M}) where {S,M,P} + + length(bound_capacities) == length(bound_metrics) || + throw(ArgumentError("Lengths of bound_capacities and bound_metrics must match")) + + new{S,M,P}(target_metric, lowerbound, upperbound, + bound_capacities, bound_metrics) + + end + +end + +minimum(x::CapacityCreditResult) = x.lowerbound +maximum(x::CapacityCreditResult) = x.upperbound +extrema(x::CapacityCreditResult) = (x.lowerbound, x.upperbound) diff --git a/src/PRAS/CapacityCredit/EFC.jl b/src/PRAS/CapacityCredit/EFC.jl new file mode 100644 index 0000000..2ff9f12 --- /dev/null +++ b/src/PRAS/CapacityCredit/EFC.jl @@ -0,0 +1,189 @@ +struct EFC{M} <: CapacityValuationMethod{M} + + capacity_max::Int + capacity_gap::Int + p_value::Float64 + regions::Vector{Tuple{String,Float64}} + verbose::Bool + + function EFC{M}( + capacity_max::Int, regions::Vector{Pair{String,Float64}}; + capacity_gap::Int=1, p_value::Float64=0.05, verbose::Bool=false) where M + + @assert capacity_max > 0 + @assert capacity_gap > 0 + @assert 0 < p_value < 1 + @assert sum(x.second for x in regions) ≈ 1.0 + + return new{M}(capacity_max, capacity_gap, p_value, Tuple.(regions), verbose) + + end + +end + +function EFC{M}( + capacity_max::Int, region::String; kwargs... +) where M + return EFC{M}(capacity_max, [region=>1.0]; kwargs...) +end + +function assess(sys_baseline::S, sys_augmented::S, + params::EFC{M}, simulationspec::SimulationSpec +) where {N, L, T, P, S <: SystemModel{N,L,T,P}, M <: ReliabilityMetric} + + _, powerunit, _ = unitsymbol(sys_baseline) + + regionnames = sys_baseline.regions.names + regionnames != sys_augmented.regions.names && + error("Systems provided do not have matching regions") + + # Add firm capacity generators to the relevant regions + efc_gens, sys_variable, sys_target = + add_firmcapacity(sys_baseline, sys_augmented, params.regions) + + target_metric = M(first(assess(sys_target, simulationspec, Shortfall()))) + + capacities = Int[] + metrics = typeof(target_metric)[] + + lower_bound = 0 + lower_bound_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, lower_bound) + push!(metrics, lower_bound_metric) + + upper_bound = params.capacity_max + update_firmcapacity!(sys_variable, efc_gens, upper_bound) + upper_bound_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, upper_bound) + push!(metrics, upper_bound_metric) + + while true + + params.verbose && println( + "\n$(lower_bound) $powerunit\t< EFC <\t$(upper_bound) $powerunit\n", + "$(lower_bound_metric)\t> $(target_metric) >\t$(upper_bound_metric)") + + midpoint = div(lower_bound + upper_bound, 2) + capacity_gap = upper_bound - lower_bound + + # Stopping conditions + + ## Return the bounds if they are within solution tolerance of each other + if capacity_gap <= params.capacity_gap + params.verbose && @info "Capacity bound gap within tolerance, stopping bisection." + break + end + + # If the null hypothesis lower_bound_metric !>= upper_bound_metric + # cannot be rejected, terminate and return the loose bounds + pval = pvalue(upper_bound_metric, lower_bound_metric) + if pval >= params.p_value + @warn "Gap between upper and lower bound risk metrics is not " * + "statistically significant (p_value=$pval), stopping bisection. " * + "The gap between capacity bounds is $(capacity_gap) $powerunit, " * + "while the target stopping gap was $(params.capacity_gap) $powerunit." + break + end + + # Evaluate metric at midpoint + update_firmcapacity!(sys_variable, efc_gens, midpoint) + midpoint_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, midpoint) + push!(metrics, midpoint_metric) + + # Tighten capacity bounds + if val(midpoint_metric) > val(target_metric) + lower_bound = midpoint + lower_bound_metric = midpoint_metric + else # midpoint_metric <= target_metric + upper_bound = midpoint + upper_bound_metric = midpoint_metric + end + + end + + return CapacityCreditResult{typeof(params), typeof(target_metric), P}( + target_metric, lower_bound, upper_bound, capacities, metrics) + +end + +function add_firmcapacity( + s1::SystemModel{N,L,T,P,E}, s2::SystemModel{N,L,T,P,E}, + region_shares::Vector{Tuple{String,Float64}} +) where {N,L,T,P,E} + + n_regions = length(s1.regions.names) + n_region_allocs = length(region_shares) + + region_allocations = allocate_regions(s1.regions.names, region_shares) + efc_gens = similar(region_allocations) + + new_gen(i::Int) = Generators{N,L,T,P}( + ["_EFC_$i"], ["_EFC Calculation Dummy Generator"], + zeros(Int, 1, N), zeros(1, N), ones(1, N)) + + variable_gens = Generators{N,L,T,P}[] + variable_region_gen_idxs = similar(s1.region_gen_idxs) + + target_gens = similar(variable_gens) + target_region_gen_idxs = similar(s2.region_gen_idxs) + + ra_idx = 0 + + for r in 1:n_regions + + s1_range = s1.region_gen_idxs[r] + s2_range = s2.region_gen_idxs[r] + + if (ra_idx < n_region_allocs) && (r == first(region_allocations[ra_idx+1])) + + ra_idx += 1 + + variable_region_gen_idxs[r] = incr_range(s1_range, ra_idx-1, ra_idx) + target_region_gen_idxs[r] = incr_range(s2_range, ra_idx-1, ra_idx) + + gen = new_gen(ra_idx) + push!(variable_gens, gen) + push!(target_gens, gen) + efc_gens[ra_idx] = ( + first(s1_range) + ra_idx - 1, + last(region_allocations[ra_idx])) + + else + + variable_region_gen_idxs[r] = incr_range(s1_range, ra_idx) + target_region_gen_idxs[r] = incr_range(s2_range, ra_idx) + + end + + push!(variable_gens, s1.generators[s1_range]) + push!(target_gens, s2.generators[s2_range]) + + end + + sys_variable = SystemModel( + s1.regions, s1.interfaces, + vcat(variable_gens...), variable_region_gen_idxs, + s1.storages, s1.region_stor_idxs, + s1.generatorstorages, s1.region_genstor_idxs, + s1.lines, s1.interface_line_idxs, s1.timestamps) + + sys_target = SystemModel( + s2.regions, s2.interfaces, + vcat(target_gens...), target_region_gen_idxs, + s2.storages, s2.region_stor_idxs, + s2.generatorstorages, s2.region_genstor_idxs, + s2.lines, s2.interface_line_idxs, s2.timestamps) + + return efc_gens, sys_variable, sys_target + +end + +function update_firmcapacity!( + sys::SystemModel, gens::Vector{Tuple{Int,Float64}}, capacity::Int) + + for (g, share) in gens + sys.generators.capacity[g, :] .= round(Int, share * capacity) + end + +end diff --git a/src/PRAS/CapacityCredit/ELCC.jl b/src/PRAS/CapacityCredit/ELCC.jl new file mode 100644 index 0000000..746290e --- /dev/null +++ b/src/PRAS/CapacityCredit/ELCC.jl @@ -0,0 +1,138 @@ +struct ELCC{M} <: CapacityValuationMethod{M} + + capacity_max::Int + capacity_gap::Int + p_value::Float64 + regions::Vector{Tuple{String,Float64}} + verbose::Bool + + function ELCC{M}( + capacity_max::Int, regions::Vector{Pair{String,Float64}}; + capacity_gap::Int=1, p_value::Float64=0.05, verbose::Bool=false) where M + + @assert capacity_max > 0 + @assert capacity_gap > 0 + @assert 0 < p_value < 1 + @assert sum(x.second for x in regions) ≈ 1.0 + + return new{M}(capacity_max, capacity_gap, p_value, Tuple.(regions), verbose) + + end + +end + +function ELCC{M}( + capacity_max::Int, region::String; kwargs... +) where M + return ELCC{M}(capacity_max, [region=>1.0]; kwargs...) +end + +function assess(sys_baseline::S, sys_augmented::S, + params::ELCC{M}, simulationspec::SimulationSpec +) where {N, L, T, P, S <: SystemModel{N,L,T,P}, M <: ReliabilityMetric} + + _, powerunit, _ = unitsymbol(sys_baseline) + + regionnames = sys_baseline.regions.names + regionnames != sys_augmented.regions.names && + error("Systems provided do not have matching regions") + + target_metric = M(first(assess(sys_baseline, simulationspec, Shortfall()))) + + capacities = Int[] + metrics = typeof(target_metric)[] + + elcc_regions, base_load, sys_variable = + copy_load(sys_augmented, params.regions) + + lower_bound = 0 + lower_bound_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, lower_bound) + push!(metrics, lower_bound_metric) + + upper_bound = params.capacity_max + update_load!(sys_variable, elcc_regions, base_load, upper_bound) + upper_bound_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, upper_bound) + push!(metrics, upper_bound_metric) + + while true + + params.verbose && println( + "\n$(lower_bound) $powerunit\t< ELCC <\t$(upper_bound) $powerunit\n", + "$(lower_bound_metric)\t< $(target_metric) <\t$(upper_bound_metric)") + + midpoint = div(lower_bound + upper_bound, 2) + capacity_gap = upper_bound - lower_bound + + # Stopping conditions + + ## Return the bounds if they are within solution tolerance of each other + if capacity_gap <= params.capacity_gap + params.verbose && @info "Capacity bound gap within tolerance, stopping bisection." + break + end + + # If the null hypothesis upper_bound_metric !>= lower_bound_metric + # cannot be rejected, terminate and return the loose bounds + pval = pvalue(lower_bound_metric, upper_bound_metric) + if pval >= params.p_value + @warn "Gap between upper and lower bound risk metrics is not " * + "statistically significant (p_value=$pval), stopping bisection. " * + "The gap between capacity bounds is $(capacity_gap) $powerunit, " * + "while the target stopping gap was $(params.capacity_gap) $powerunit." + break + end + + # Evaluate metric at midpoint + update_load!(sys_variable, elcc_regions, base_load, midpoint) + midpoint_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) + push!(capacities, midpoint) + push!(metrics, midpoint_metric) + + # Tighten capacity bounds + if val(midpoint_metric) < val(target_metric) + lower_bound = midpoint + lower_bound_metric = midpoint_metric + else # midpoint_metric <= target_metric + upper_bound = midpoint + upper_bound_metric = midpoint_metric + end + + end + + return CapacityCreditResult{typeof(params), typeof(target_metric), P}( + target_metric, lower_bound, upper_bound, capacities, metrics) + +end + +function copy_load( + sys::SystemModel{N,L,T,P,E}, + region_shares::Vector{Tuple{String,Float64}} +) where {N,L,T,P,E} + + region_allocations = allocate_regions(sys.regions.names, region_shares) + + new_regions = Regions{N,P}(sys.regions.names, copy(sys.regions.load)) + + return region_allocations, sys.regions.load, SystemModel( + new_regions, sys.interfaces, + sys.generators, sys.region_gen_idxs, + sys.storages, sys.region_stor_idxs, + sys.generatorstorages, sys.region_genstor_idxs, + sys.lines, sys.interface_line_idxs, sys.timestamps) + +end + +function update_load!( + sys::SystemModel, + region_shares::Vector{Tuple{Int,Float64}}, + load_base::Matrix{Int}, + load_increase::Int +) + for (r, share) in region_shares + sys.regions.load[r, :] .= load_base[r, :] .+ + round(Int, share * load_increase) + end + +end diff --git a/src/PRAS/CapacityCredit/utils.jl b/src/PRAS/CapacityCredit/utils.jl new file mode 100644 index 0000000..2f09a4a --- /dev/null +++ b/src/PRAS/CapacityCredit/utils.jl @@ -0,0 +1,45 @@ +function pvalue(lower::T, upper::T) where {T<:ReliabilityMetric} + + vl = val(lower) + sl = stderror(lower) + + vu = val(upper) + su = stderror(upper) + + if iszero(sl) && iszero(su) + result = Float64(vl ≈ vu) + else + # single-sided z-test with null hypothesis that (vu - vl) not > 0 + z = (vu - vl) / sqrt(su^2 + sl^2) + result = ccdf(Normal(), z) + end + + return result + +end + +function allocate_regions( + region_names::Vector{String}, + regionname_shares::Vector{Tuple{String,Float64}} +) + + region_allocations = similar(regionname_shares, Tuple{Int,Float64}) + + for (i, (name, share)) in enumerate(regionname_shares) + + r = findfirst(isequal(name), region_names) + + isnothing(r) && + error("$name is not a region name in the provided systems") + + region_allocations[i] = (r, share) + + end + + return sort!(region_allocations) + +end + +incr_range(rnge::UnitRange{Int}, inc::Int) = rnge .+ inc +incr_range(rnge::UnitRange{Int}, inc1::Int, inc2::Int) = + (first(rnge) + inc1):(last(rnge) + inc2) diff --git a/src/PRAS/PRAS.jl b/src/PRAS/PRAS.jl new file mode 100644 index 0000000..c5e729f --- /dev/null +++ b/src/PRAS/PRAS.jl @@ -0,0 +1,13 @@ +module PRAS + +using Reexport + +const PRAS_VERSION = "v0.6.0" + +include("PRASBase/PRASBase.jl") +include("ResourceAdequacy/ResourceAdequacy.jl") +include("CapacityCredit/CapacityCredit.jl") + +import .PRASBase: rts_gmlc,toymodel + +end diff --git a/src/PRAS/PRASBase/PRASBase.jl b/src/PRAS/PRASBase/PRASBase.jl new file mode 100644 index 0000000..75e9f97 --- /dev/null +++ b/src/PRAS/PRASBase/PRASBase.jl @@ -0,0 +1,43 @@ +@reexport module PRASBase + +import ..PRAS_VERSION + +import Base: broadcastable + +import Dates: @dateformat_str, AbstractDateTime, DateTime, + Period, Minute, Hour, Day, Year + +import HDF5: HDF5, attributes, File, Group, Dataset, Datatype, dataspace, + h5open, create_group, create_dataset, hdf5_type_id + +import HDF5.API: h5t_create, h5t_copy, h5t_insert, h5t_set_size, H5T_COMPOUND, + h5d_write, H5S_ALL, H5P_DEFAULT + +import TimeZones: TimeZone, ZonedDateTime + +export + + # System assets + Regions, Interfaces, + AbstractAssets, Generators, Storages, GeneratorStorages, Lines, + + # Units + Period, Minute, Hour, Day, Year, + PowerUnit, kW, MW, GW, TW, + EnergyUnit, kWh, MWh, GWh, TWh, + unitsymbol, conversionfactor, powertoenergy, energytopower, + + # Main data structure + SystemModel, savemodel + +include("units.jl") +include("collections.jl") +include("assets.jl") +include("SystemModel.jl") + +include("read.jl") +include("write.jl") + +include("utils.jl") + +end diff --git a/src/PRAS/PRASBase/SystemModel.jl b/src/PRAS/PRASBase/SystemModel.jl new file mode 100644 index 0000000..119c465 --- /dev/null +++ b/src/PRAS/PRASBase/SystemModel.jl @@ -0,0 +1,156 @@ +struct SystemModel{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} + + regions::Regions{N,P} + interfaces::Interfaces{N,P} + + generators::Generators{N,L,T,P} + region_gen_idxs::Vector{UnitRange{Int}} + + storages::Storages{N,L,T,P,E} + region_stor_idxs::Vector{UnitRange{Int}} + + generatorstorages::GeneratorStorages{N,L,T,P,E} + region_genstor_idxs::Vector{UnitRange{Int}} + + lines::Lines{N,L,T,P} + interface_line_idxs::Vector{UnitRange{Int}} + + timestamps::StepRange{ZonedDateTime,T} + + function SystemModel{}( + regions::Regions{N,P}, interfaces::Interfaces{N,P}, + generators::Generators{N,L,T,P}, region_gen_idxs::Vector{UnitRange{Int}}, + storages::Storages{N,L,T,P,E}, region_stor_idxs::Vector{UnitRange{Int}}, + generatorstorages::GeneratorStorages{N,L,T,P,E}, + region_genstor_idxs::Vector{UnitRange{Int}}, + lines::Lines{N,L,T,P}, interface_line_idxs::Vector{UnitRange{Int}}, + timestamps::StepRange{ZonedDateTime,T} + ) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} + + n_regions = length(regions) + n_gens = length(generators) + n_stors = length(storages) + n_genstors = length(generatorstorages) + + n_interfaces = length(interfaces) + n_lines = length(lines) + + @assert consistent_idxs(region_gen_idxs, n_gens, n_regions) + @assert consistent_idxs(region_stor_idxs, n_stors, n_regions) + @assert consistent_idxs(region_genstor_idxs, n_genstors, n_regions) + @assert consistent_idxs(interface_line_idxs, n_lines, n_interfaces) + + @assert all( + 1 <= interfaces.regions_from[i] < interfaces.regions_to[i] <= n_regions + for i in 1:n_interfaces) + + @assert step(timestamps) == T(L) + @assert length(timestamps) == N + + new{N,L,T,P,E}( + regions, interfaces, + generators, region_gen_idxs, storages, region_stor_idxs, + generatorstorages, region_genstor_idxs, lines, interface_line_idxs, + timestamps) + + end + +end + +# No time zone constructor +function SystemModel( + regions::Regions{N,P}, interfaces::Interfaces{N,P}, + generators::Generators{N,L,T,P}, region_gen_idxs::Vector{UnitRange{Int}}, + storages::Storages{N,L,T,P,E}, region_stor_idxs::Vector{UnitRange{Int}}, + generatorstorages::GeneratorStorages{N,L,T,P,E}, region_genstor_idxs::Vector{UnitRange{Int}}, + lines, interface_line_idxs::Vector{UnitRange{Int}}, + timestamps::StepRange{DateTime,T} +) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} + + @warn "No time zone data provided - defaulting to UTC. To specify a " * + "time zone for the system timestamps, provide a range of " * + "`ZonedDateTime` instead of `DateTime`." + + utc = TimeZone("UTC") + time_start = ZonedDateTime(first(timestamps), utc) + time_end = ZonedDateTime(last(timestamps), utc) + timestamps_tz = time_start:step(timestamps):time_end + + return SystemModel( + regions, interfaces, + generators, region_gen_idxs, + storages, region_stor_idxs, + generatorstorages, region_genstor_idxs, + lines, interface_line_idxs, + timestamps_tz) + +end + +# Single-node constructor +function SystemModel( + generators::Generators{N,L,T,P}, + storages::Storages{N,L,T,P,E}, + generatorstorages::GeneratorStorages{N,L,T,P,E}, + timestamps::StepRange{<:AbstractDateTime,T}, + load::Vector{Int} +) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} + + return SystemModel( + Regions{N,P}(["Region"], reshape(load, 1, :)), + Interfaces{N,P}( + Int[], Int[], + Matrix{Int}(undef, 0, N), Matrix{Int}(undef, 0, N)), + generators, [1:length(generators)], + storages, [1:length(storages)], + generatorstorages, [1:length(generatorstorages)], + Lines{N,L,T,P}( + String[], String[], + Matrix{Int}(undef, 0, N), Matrix{Int}(undef, 0, N), + Matrix{Float64}(undef, 0, N), Matrix{Float64}(undef, 0, N)), + UnitRange{Int}[], timestamps) + +end + +Base.:(==)(x::T, y::T) where {T <: SystemModel} = + x.regions == y.regions && + x.interfaces == y.interfaces && + x.generators == y.generators && + x.region_gen_idxs == y.region_gen_idxs && + x.storages == y.storages && + x.region_stor_idxs == y.region_stor_idxs && + x.generatorstorages == y.generatorstorages && + x.region_genstor_idxs == y.region_genstor_idxs && + x.lines == y.lines && + x.interface_line_idxs == y.interface_line_idxs && + x.timestamps == y.timestamps + +broadcastable(x::SystemModel) = Ref(x) + +unitsymbol(::SystemModel{N,L,T,P,E}) where { + N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} = + unitsymbol(T), unitsymbol(P), unitsymbol(E) + +function consistent_idxs(idxss::Vector{UnitRange{Int}}, nitems::Int, ngroups::Int) + + length(idxss) == ngroups || return false + + expected_next = 1 + for idxs in idxss + first(idxs) == expected_next || return false + expected_next = last(idxs) + 1 + end + + expected_next == nitems + 1 || return false + return true + +end + +function rts_gmlc() + path = dirname(@__FILE__) + return SystemModel(path * "/rts.pras") +end + +function toymodel() + path = dirname(@__FILE__) + return SystemModel(path * "/toymodel.pras") +end \ No newline at end of file diff --git a/src/PRAS/PRASBase/assets.jl b/src/PRAS/PRASBase/assets.jl new file mode 100644 index 0000000..14c13d1 --- /dev/null +++ b/src/PRAS/PRASBase/assets.jl @@ -0,0 +1,441 @@ +abstract type AbstractAssets{N,L,T<:Period,P<:PowerUnit} end +Base.length(a::AbstractAssets) = length(a.names) + +struct Generators{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} + + names::Vector{String} + categories::Vector{String} + + capacity::Matrix{Int} # power + + λ::Matrix{Float64} + μ::Matrix{Float64} + + function Generators{N,L,T,P}( + names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, + capacity::Matrix{Int}, λ::Matrix{Float64}, μ::Matrix{Float64} + ) where {N,L,T,P} + + n_gens = length(names) + @assert length(categories) == n_gens + @assert allunique(names) + + @assert size(capacity) == (n_gens, N) + @assert all(capacity .>= 0) # Why not just use unsigned integers? + + @assert size(λ) == (n_gens, N) + @assert size(μ) == (n_gens, N) + @assert all(0 .<= λ .<= 1) + @assert all(0 .<= μ .<= 1) + + new{N,L,T,P}(string.(names), string.(categories), capacity, λ, μ) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: Generators} = + x.names == y.names && + x.categories == y.categories && + x.capacity == y.capacity && + x.λ == y.λ && + x.μ == y.μ + +Base.getindex(g::G, idxs::AbstractVector{Int}) where {G <: Generators} = + G(g.names[idxs], g.categories[idxs], + g.capacity[idxs, :], g.λ[idxs, :], g.μ[idxs, :]) + +function Base.vcat(gs::Generators{N,L,T,P}...) where {N, L, T, P} + + n_gens = sum(length(g) for g in gs) + + names = Vector{String}(undef, n_gens) + categories = Vector{String}(undef, n_gens) + + capacity = Matrix{Int}(undef, n_gens, N) + + λ = Matrix{Float64}(undef, n_gens, N) + μ = Matrix{Float64}(undef, n_gens, N) + + last_idx = 0 + + for g in gs + + n = length(g) + rows = last_idx .+ (1:n) + + names[rows] = g.names + categories[rows] = g.categories + capacity[rows, :] = g.capacity + λ[rows, :] = g.λ + μ[rows, :] = g.μ + + last_idx += n + + end + + return Generators{N,L,T,P}(names, categories, capacity, λ, μ) + +end + +struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P} + + names::Vector{String} + categories::Vector{String} + + charge_capacity::Matrix{Int} # power + discharge_capacity::Matrix{Int} # power + energy_capacity::Matrix{Int} # energy + + charge_efficiency::Matrix{Float64} + discharge_efficiency::Matrix{Float64} + carryover_efficiency::Matrix{Float64} + + λ::Matrix{Float64} + μ::Matrix{Float64} + + function Storages{N,L,T,P,E}( + names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, + chargecapacity::Matrix{Int}, dischargecapacity::Matrix{Int}, + energycapacity::Matrix{Int}, chargeefficiency::Matrix{Float64}, + dischargeefficiency::Matrix{Float64}, carryoverefficiency::Matrix{Float64}, + λ::Matrix{Float64}, μ::Matrix{Float64} + ) where {N,L,T,P,E} + + n_stors = length(names) + @assert length(categories) == n_stors + @assert allunique(names) + + @assert size(chargecapacity) == (n_stors, N) + @assert size(dischargecapacity) == (n_stors, N) + @assert size(energycapacity) == (n_stors, N) + @assert all(chargecapacity .>= 0) + @assert all(dischargecapacity .>= 0) + @assert all(energycapacity .>= 0) + + @assert size(chargeefficiency) == (n_stors, N) + @assert size(dischargeefficiency) == (n_stors, N) + @assert size(carryoverefficiency) == (n_stors, N) + @assert all(0 .< chargeefficiency .<= 1) + @assert all(0 .< dischargeefficiency .<= 1) + @assert all(0 .< carryoverefficiency .<= 1) + + @assert size(λ) == (n_stors, N) + @assert size(μ) == (n_stors, N) + @assert all(0 .<= λ .<= 1) + @assert all(0 .<= μ .<= 1) + + new{N,L,T,P,E}(string.(names), string.(categories), + chargecapacity, dischargecapacity, energycapacity, + chargeefficiency, dischargeefficiency, carryoverefficiency, + λ, μ) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: Storages} = + x.names == y.names && + x.categories == y.categories && + x.charge_capacity == y.charge_capacity && + x.discharge_capacity == y.discharge_capacity && + x.energy_capacity == y.energy_capacity && + x.charge_efficiency == y.charge_efficiency && + x.discharge_efficiency == y.discharge_efficiency && + x.carryover_efficiency == y.carryover_efficiency && + x.λ == y.λ && + x.μ == y.μ + +Base.getindex(s::S, idxs::AbstractVector{Int}) where {S <: Storages} = + S(s.names[idxs], s.categories[idxs],s.charge_capacity[idxs,:], + s.discharge_capacity[idxs, :],s.energy_capacity[idxs, :], + s.charge_efficiency[idxs, :], s.discharge_efficiency[idxs, :], + s.carryover_efficiency[idxs, :],s.λ[idxs, :], s.μ[idxs, :]) + +function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E} + + n_stors = sum(length(s) for s in stors) + + names = Vector{String}(undef, n_stors) + categories = Vector{String}(undef, n_stors) + + charge_capacity = Matrix{Int}(undef, n_stors, N) + discharge_capacity = Matrix{Int}(undef, n_stors, N) + energy_capacity = Matrix{Int}(undef, n_stors, N) + + charge_efficiency = Matrix{Float64}(undef, n_stors, N) + discharge_efficiency = Matrix{Float64}(undef, n_stors, N) + carryover_efficiency = Matrix{Float64}(undef, n_stors, N) + + λ = Matrix{Float64}(undef, n_stors, N) + μ = Matrix{Float64}(undef, n_stors, N) + + last_idx = 0 + + for s in stors + + n = length(s) + rows = last_idx .+ (1:n) + + names[rows] = s.names + categories[rows] = s.categories + + charge_capacity[rows, :] = s.charge_capacity + discharge_capacity[rows, :] = s.discharge_capacity + energy_capacity[rows, :] = s.energy_capacity + + charge_efficiency[rows, :] = s.charge_efficiency + discharge_efficiency[rows, :] = s.discharge_efficiency + carryover_efficiency[rows, :] = s.carryover_efficiency + + λ[rows, :] = s.λ + μ[rows, :] = s.μ + + last_idx += n + + end + + return Storages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency, + carryover_efficiency, λ, μ) + +end + +struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P} + + names::Vector{String} + categories::Vector{String} + + charge_capacity::Matrix{Int} # power + discharge_capacity::Matrix{Int} # power + energy_capacity::Matrix{Int} # energy + + charge_efficiency::Matrix{Float64} + discharge_efficiency::Matrix{Float64} + carryover_efficiency::Matrix{Float64} + + inflow::Matrix{Int} # power + gridwithdrawal_capacity::Matrix{Int} # power + gridinjection_capacity::Matrix{Int} # power + + λ::Matrix{Float64} + μ::Matrix{Float64} + + function GeneratorStorages{N,L,T,P,E}( + names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, + charge_capacity::Matrix{Int}, discharge_capacity::Matrix{Int}, + energy_capacity::Matrix{Int}, + charge_efficiency::Matrix{Float64}, discharge_efficiency::Matrix{Float64}, + carryover_efficiency::Matrix{Float64}, + inflow::Matrix{Int}, + gridwithdrawal_capacity::Matrix{Int}, gridinjection_capacity::Matrix{Int}, + λ::Matrix{Float64}, μ::Matrix{Float64} + ) where {N,L,T,P,E} + + n_stors = length(names) + @assert length(categories) == n_stors + @assert allunique(names) + + @assert size(charge_capacity) == (n_stors, N) + @assert size(discharge_capacity) == (n_stors, N) + @assert size(energy_capacity) == (n_stors, N) + + @assert all(charge_capacity .>= 0) + @assert all(discharge_capacity .>= 0) + @assert all(energy_capacity .>= 0) + + @assert size(charge_efficiency) == (n_stors, N) + @assert size(discharge_efficiency) == (n_stors, N) + @assert size(carryover_efficiency) == (n_stors, N) + + @assert all(0 .< charge_efficiency .<= 1) + @assert all(0 .< discharge_efficiency .<= 1) + @assert all(0 .< carryover_efficiency .<= 1) + + @assert size(inflow) == (n_stors, N) + @assert size(gridwithdrawal_capacity) == (n_stors, N) + @assert size(gridinjection_capacity) == (n_stors, N) + + @assert all(inflow .>= 0) + @assert all(gridwithdrawal_capacity .>= 0) + @assert all(gridinjection_capacity .>= 0) + + @assert size(λ) == (n_stors, N) + @assert size(μ) == (n_stors, N) + @assert all(0 .<= λ .<= 1) + @assert all(0 .<= μ .<= 1) + + new{N,L,T,P,E}( + string.(names), string.(categories), + charge_capacity, discharge_capacity, energy_capacity, + charge_efficiency, discharge_efficiency, carryover_efficiency, + inflow, gridwithdrawal_capacity, gridinjection_capacity, + λ, μ) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: GeneratorStorages} = + x.names == y.names && + x.categories == y.categories && + x.charge_capacity == y.charge_capacity && + x.discharge_capacity == y.discharge_capacity && + x.energy_capacity == y.energy_capacity && + x.charge_efficiency == y.charge_efficiency && + x.discharge_efficiency == y.discharge_efficiency && + x.carryover_efficiency == y.carryover_efficiency && + x.inflow == y.inflow && + x.gridwithdrawal_capacity == y.gridwithdrawal_capacity && + x.gridinjection_capacity == y.gridinjection_capacity && + x.λ == y.λ && + x.μ == y.μ + +Base.getindex(g_s::G, idxs::AbstractVector{Int}) where {G <: GeneratorStorages} = + G(g_s.names[idxs], g_s.categories[idxs], g_s.charge_capacity[idxs,:], + g_s.discharge_capacity[idxs, :], g_s.energy_capacity[idxs, :], + g_s.charge_efficiency[idxs, :], g_s.discharge_efficiency[idxs, :], + g_s.carryover_efficiency[idxs, :],g_s.inflow[idxs, :], + g_s.gridwithdrawal_capacity[idxs, :],g_s.gridinjection_capacity[idxs, :], + g_s.λ[idxs, :], g_s.μ[idxs, :]) + +function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P, E} + + n_gen_stors = sum(length(g_s) for g_s in gen_stors) + + names = Vector{String}(undef, n_gen_stors) + categories = Vector{String}(undef, n_gen_stors) + + charge_capacity = Matrix{Int}(undef, n_gen_stors, N) + discharge_capacity = Matrix{Int}(undef, n_gen_stors, N) + energy_capacity = Matrix{Int}(undef, n_gen_stors, N) + + charge_efficiency = Matrix{Float64}(undef, n_gen_stors, N) + discharge_efficiency = Matrix{Float64}(undef, n_gen_stors, N) + carryover_efficiency = Matrix{Float64}(undef, n_gen_stors, N) + + inflow = Matrix{Int}(undef, n_gen_stors, N) + gridwithdrawal_capacity = Matrix{Int}(undef, n_gen_stors, N) + gridinjection_capacity = Matrix{Int}(undef, n_gen_stors, N) + + λ = Matrix{Float64}(undef, n_gen_stors, N) + μ = Matrix{Float64}(undef, n_gen_stors, N) + + last_idx = 0 + + for g_s in gen_stors + + n = length(g_s) + rows = last_idx .+ (1:n) + + names[rows] = g_s.names + categories[rows] = g_s.categories + + charge_capacity[rows, :] = g_s.charge_capacity + discharge_capacity[rows, :] = g_s.discharge_capacity + energy_capacity[rows, :] = g_s.energy_capacity + + charge_efficiency[rows, :] = g_s.charge_efficiency + discharge_efficiency[rows, :] = g_s.discharge_efficiency + carryover_efficiency[rows, :] = g_s.carryover_efficiency + + inflow[rows, :] = g_s.inflow + gridwithdrawal_capacity[rows, :] = g_s.gridwithdrawal_capacity + gridinjection_capacity[rows, :] = g_s.gridinjection_capacity + + λ[rows, :] = g_s.λ + μ[rows, :] = g_s.μ + + last_idx += n + + end + + return GeneratorStorages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency, + carryover_efficiency,inflow, gridwithdrawal_capacity, gridinjection_capacity, λ, μ) + +end + +struct Lines{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} + + names::Vector{String} + categories::Vector{String} + + forward_capacity::Matrix{Int} # power + backward_capacity::Matrix{Int} # power + + λ::Matrix{Float64} + μ::Matrix{Float64} + + function Lines{N,L,T,P}( + names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, + forward_capacity::Matrix{Int}, backward_capacity::Matrix{Int}, + λ::Matrix{Float64}, μ::Matrix{Float64} + ) where {N,L,T,P} + + n_lines = length(names) + @assert length(categories) == n_lines + @assert allunique(names) + + @assert size(forward_capacity) == (n_lines, N) + @assert size(backward_capacity) == (n_lines, N) + @assert all(forward_capacity .>= 0) + @assert all(backward_capacity .>= 0) + + @assert size(λ) == (n_lines, N) + @assert size(μ) == (n_lines, N) + @assert all(0 .<= λ .<= 1) + @assert all(0 .<= μ .<= 1) + + new{N,L,T,P}(string.(names), string.(categories), forward_capacity, backward_capacity, λ, μ) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: Lines} = + x.names == y.names && + x.categories == y.categories && + x.forward_capacity == y.forward_capacity && + x.backward_capacity == y.backward_capacity && + x.λ == y.λ && + x.μ == y.μ + +Base.getindex(lines::L, idxs::AbstractVector{Int}) where {L <: Lines} = + L(lines.names[idxs], lines.categories[idxs],lines.forward_capacity[idxs,:], + lines.backward_capacity[idxs, :],lines.λ[idxs, :], lines.μ[idxs, :]) + +function Base.vcat(lines::Lines{N,L,T,P}...) where {N, L, T, P} + + n_lines = sum(length(line) for line in lines) + + names = Vector{String}(undef, n_lines) + categories = Vector{String}(undef, n_lines) + + forward_capacity = Matrix{Int}(undef, n_lines, N) + backward_capacity = Matrix{Int}(undef, n_lines, N) + + λ = Matrix{Float64}(undef,n_lines, N) + μ = Matrix{Float64}(undef,n_lines, N) + + last_idx = 0 + + for line in lines + + n = length(line) + rows = last_idx .+ (1:n) + + names[rows] = line.names + categories[rows] = line.categories + + forward_capacity[rows, :] = line.forward_capacity + backward_capacity[rows, :] = line.backward_capacity + + λ[rows, :] = line.λ + μ[rows, :] = line.μ + + last_idx += n + + end + + return Lines{N,L,T,P}(names, categories, forward_capacity, backward_capacity, λ, μ) + +end \ No newline at end of file diff --git a/src/PRAS/PRASBase/collections.jl b/src/PRAS/PRASBase/collections.jl new file mode 100644 index 0000000..e1b003a --- /dev/null +++ b/src/PRAS/PRASBase/collections.jl @@ -0,0 +1,59 @@ +struct Regions{N,P<:PowerUnit} + + names::Vector{String} + load::Matrix{Int} + + function Regions{N,P}( + names::Vector{<:AbstractString}, load::Matrix{Int} + ) where {N,P<:PowerUnit} + + n_regions = length(names) + + @assert size(load) == (n_regions, N) + @assert all(load .>= 0) + + new{N,P}(string.(names), load) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: Regions} = + x.names == y.names && + x.load == y.load + +Base.length(r::Regions) = length(r.names) + +struct Interfaces{N,P<:PowerUnit} + + regions_from::Vector{Int} + regions_to::Vector{Int} + limit_forward::Matrix{Int} + limit_backward::Matrix{Int} + + function Interfaces{N,P}( + regions_from::Vector{Int}, regions_to::Vector{Int}, + forwardcapacity::Matrix{Int}, backwardcapacity::Matrix{Int} + ) where {N,P<:PowerUnit} + + n_interfaces = length(regions_from) + @assert length(regions_to) == n_interfaces + + @assert size(forwardcapacity) == (n_interfaces, N) + @assert size(backwardcapacity) == (n_interfaces, N) + @assert all(forwardcapacity .>= 0) + @assert all(backwardcapacity .>= 0) + + new{N,P}(regions_from, regions_to, forwardcapacity, backwardcapacity) + + end + +end + +Base.:(==)(x::T, y::T) where {T <: Interfaces} = + x.regions_from == y.regions_from && + x.regions_to == y.regions_to && + x.limit_forward == y.limit_forward && + x.limit_backward == y.limit_backward + +Base.length(i::Interfaces) = length(i.regions_from) diff --git a/src/PRAS/PRASBase/read.jl b/src/PRAS/PRASBase/read.jl new file mode 100644 index 0000000..a600c38 --- /dev/null +++ b/src/PRAS/PRASBase/read.jl @@ -0,0 +1,292 @@ +""" + + SystemModel(filename::String) + +Load a `SystemModel` from an appropriately-formatted HDF5 file on disk. +""" +function SystemModel(inputfile::String) + + system = h5open(inputfile, "r") do f::File + + version, versionstring = readversion(f) + + # Determine the appropriate version of the importer to use + return if (0,5,0) <= version < (0,7,0) + systemmodel_0_5(f) + else + error("PRAS file format $versionstring not supported by this version of PRASBase.") + end + + end + + return system + +end + + +function systemmodel_0_5(f::File) + + metadata = attributes(f) + + start_timestamp = ZonedDateTime(read(metadata["start_timestamp"]), + dateformat"yyyy-mm-ddTHH:MM:SSz") + + N = Int(read(metadata["timestep_count"])) + L = Int(read(metadata["timestep_length"])) + T = timeunits[read(metadata["timestep_unit"])] + P = powerunits[read(metadata["power_unit"])] + E = energyunits[read(metadata["energy_unit"])] + + timestep = T(L) + end_timestamp = start_timestamp + (N-1)*timestep + timestamps = StepRange(start_timestamp, timestep, end_timestamp) + + has_regions = haskey(f, "regions") + has_generators = haskey(f, "generators") + has_storages = haskey(f, "storages") + has_generatorstorages = haskey(f, "generatorstorages") + has_interfaces = haskey(f, "interfaces") + has_lines = haskey(f, "lines") + + has_regions || + error("Region data must be provided") + + has_generators || has_generatorstorages || + error("Generator or generator storage data (or both) must be provided") + + xor(has_interfaces, has_lines) && + error("Both (or neither) interface and line data must be provided") + + regionnames = readvector(f["regions/_core"], :name) + regions = Regions{N,P}( + regionnames, + Int.(read(f["regions/load"])) + ) + regionlookup = Dict(n=>i for (i, n) in enumerate(regionnames)) + n_regions = length(regions) + + if has_generators + + gen_core = read(f["generators/_core"]) + gen_names, gen_categories, gen_regionnames = readvector.( + Ref(gen_core), [:name, :category, :region]) + + gen_regions = getindex.(Ref(regionlookup), gen_regionnames) + region_order = sortperm(gen_regions) + + generators = Generators{N,L,T,P}( + gen_names[region_order], gen_categories[region_order], + Int.(read(f["generators/capacity"]))[region_order, :], + read(f["generators/failureprobability"])[region_order, :], + read(f["generators/repairprobability"])[region_order, :] + ) + + region_gen_idxs = makeidxlist(gen_regions[region_order], n_regions) + + else + + generators = Generators{N,L,T,P}( + String[], String[], zeros(Int, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N)) + + region_gen_idxs = fill(1:0, n_regions) + + end + + if has_storages + + stor_core = read(f["storages/_core"]) + stor_names, stor_categories, stor_regionnames = readvector.( + Ref(stor_core), [:name, :category, :region]) + + stor_regions = getindex.(Ref(regionlookup), stor_regionnames) + region_order = sortperm(stor_regions) + + storages = Storages{N,L,T,P,E}( + stor_names[region_order], stor_categories[region_order], + Int.(read(f["storages/chargecapacity"]))[region_order, :], + Int.(read(f["storages/dischargecapacity"]))[region_order, :], + Int.(read(f["storages/energycapacity"]))[region_order, :], + read(f["storages/chargeefficiency"])[region_order, :], + read(f["storages/dischargeefficiency"])[region_order, :], + read(f["storages/carryoverefficiency"])[region_order, :], + read(f["storages/failureprobability"])[region_order, :], + read(f["storages/repairprobability"])[region_order, :] + ) + + region_stor_idxs = makeidxlist(stor_regions[region_order], n_regions) + + else + + storages = Storages{N,L,T,P,E}( + String[], String[], + zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N)) + + region_stor_idxs = fill(1:0, n_regions) + + end + + + if has_generatorstorages + + genstor_core = read(f["generatorstorages/_core"]) + genstor_names, genstor_categories, genstor_regionnames = readvector.( + Ref(genstor_core), [:name, :category, :region]) + + genstor_regions = getindex.(Ref(regionlookup), genstor_regionnames) + region_order = sortperm(genstor_regions) + + generatorstorages = GeneratorStorages{N,L,T,P,E}( + genstor_names[region_order], genstor_categories[region_order], + Int.(read(f["generatorstorages/chargecapacity"]))[region_order, :], + Int.(read(f["generatorstorages/dischargecapacity"]))[region_order, :], + Int.(read(f["generatorstorages/energycapacity"]))[region_order, :], + read(f["generatorstorages/chargeefficiency"])[region_order, :], + read(f["generatorstorages/dischargeefficiency"])[region_order, :], + read(f["generatorstorages/carryoverefficiency"])[region_order, :], + Int.(read(f["generatorstorages/inflow"]))[region_order, :], + Int.(read(f["generatorstorages/gridwithdrawalcapacity"]))[region_order, :], + Int.(read(f["generatorstorages/gridinjectioncapacity"]))[region_order, :], + read(f["generatorstorages/failureprobability"])[region_order, :], + read(f["generatorstorages/repairprobability"])[region_order, :]) + + region_genstor_idxs = makeidxlist(genstor_regions[region_order], n_regions) + + else + + generatorstorages = GeneratorStorages{N,L,T,P,E}( + String[], String[], + zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N), + zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N)) + + region_genstor_idxs = fill(1:0, n_regions) + + end + + if has_interfaces + + interfaces_core = read(f["interfaces/_core"]) + from_regionnames, to_regionnames = + readvector.(Ref(interfaces_core), [:region_from, :region_to]) + forwardcapacity = Int.(read(f["interfaces/forwardcapacity"])) + backwardcapacity = Int.(read(f["interfaces/backwardcapacity"])) + + n_interfaces = length(from_regionnames) + from_regions = getindex.(Ref(regionlookup), from_regionnames) + to_regions = getindex.(Ref(regionlookup), to_regionnames) + + # Force interface definitions as smaller => larger region numbers + for i in 1:n_interfaces + from_region = from_regions[i] + to_region = to_regions[i] + if from_region > to_region + from_regions[i] = to_region + to_regions[i] = from_region + new_forwardcapacity = backwardcapacity[i, :] + backwardcapacity[i, :] .= forwardcapacity[i, :] + forwardcapacity[i, :] .= new_forwardcapacity + elseif from_region == to_region + error("Cannot have an interface to and from " * + "the same region ($(from_region))") + end + end + + interfaces = Interfaces{N,P}( + from_regions, to_regions, forwardcapacity, backwardcapacity) + + interface_lookup = Dict((r1, r2) => i for (i, (r1, r2)) + in enumerate(tuple.(from_regions, to_regions))) + + lines_core = read(f["lines/_core"]) + line_names, line_categories, line_fromregionnames, line_toregionnames = + readvector.(Ref(lines_core), [:name, :category, :region_from, :region_to]) + line_forwardcapacity = Int.(read(f["lines/forwardcapacity"])) + line_backwardcapacity = Int.(read(f["lines/backwardcapacity"])) + + n_lines = length(line_names) + line_fromregions = getindex.(Ref(regionlookup), line_fromregionnames) + line_toregions = getindex.(Ref(regionlookup), line_toregionnames) + + # Force line definitions as smaller => larger region numbers + for i in 1:n_lines + from_region = line_fromregions[i] + to_region = line_toregions[i] + if from_region > to_region + line_fromregions[i] = to_region + line_toregions[i] = from_region + new_forwardcapacity = line_backwardcapacity[i, :] + line_backwardcapacity[i, :] .= line_forwardcapacity[i, :] + line_forwardcapacity[i, :] = new_forwardcapacity + elseif from_region == to_region + error("Cannot have a line ($(line_names[i])) to and from " * + "the same region ($(from_region))") + end + end + + line_interfaces = getindex.(Ref(interface_lookup), + tuple.(line_fromregions, line_toregions)) + interface_order = sortperm(line_interfaces) + + lines = Lines{N,L,T,P}( + line_names[interface_order], line_categories[interface_order], + line_forwardcapacity[interface_order, :], + line_backwardcapacity[interface_order, :], + read(f["lines/failureprobability"])[interface_order, :], + read(f["lines/repairprobability"])[interface_order, :]) + + interface_line_idxs = makeidxlist(line_interfaces[interface_order], n_interfaces) + + else + + interfaces = Interfaces{N,P}( + Int[], Int[], zeros(Int, 0, N), zeros(Int, 0, N)) + + lines = Lines{N,L,T,P}( + String[], String[], zeros(Int, 0, N), zeros(Int, 0, N), + zeros(Float64, 0, N), zeros(Float64, 0, N)) + + interface_line_idxs = UnitRange{Int}[] + + end + + return SystemModel( + regions, interfaces, + generators, region_gen_idxs, + storages, region_stor_idxs, + generatorstorages, region_genstor_idxs, + lines, interface_line_idxs, + timestamps) + +end + +""" +Attempts to parse the file's "vX.Y.Z" version label into (x::Int, y::Int, z::Int). +Errors if the label cannot be found or parsed as expected. +""" +function readversion(f::File) + + haskey(attributes(f), "pras_dataversion") || error( + "File format version indicator could not be found - the file may " * + "not be a PRAS SystemModel representation.") + + versionstring = read(attributes(f)["pras_dataversion"]) + + version = match(r"^v(\d+)\.(\d+)\.(\d+)$", versionstring) + isnothing(version) && error("File format version $versionstring not recognized") + + major, minor, patch = parse.(Int, version.captures) + + return (major, minor, patch), versionstring + +end + +""" +Attempts to extract a vector of elements from an HDF5 compound datatype, +corresponding to `field`. +""" +readvector(d::Dataset, field::Union{Symbol,Int}) = readvector(read(d), field) +readvector(d::Vector{<:NamedTuple}, field::Union{Symbol,Int}) = getindex.(d, field) diff --git a/src/PRAS/PRASBase/rts.pras b/src/PRAS/PRASBase/rts.pras new file mode 100644 index 0000000000000000000000000000000000000000..5a70afffcdf5b33ae75ecc87ae071948e6f469fb GIT binary patch literal 979488 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
    W{io$D^epFP zP-6At{ejAOf2h7JYF5&`mlK9t5qz)tT)p1qhdEYvVv$7X2vU*GcWdVd+aVb)@Jzp| zp7@>OSg#FdniuhEQK-F6p=RJ2L7Gje?Cpa68)Hq~nX{{gRq>zS45JHrif$BVm$%`p zNi|#7N2P1x1Co*wWM$04{Jm2|4Qqpzd?WT|`Hlf0UXW2Q*$D}|Nn^HCE^B5tS>*&U zD|}#2g!48gH9F(rrjU{YmV+P34~xc4wp53n`^oUGD=Y0I z-Zw?UA#RHCIT`Cfd>{YjlGIRjQrq2Nmw745oM*J^*bUN9j|Kr0{!BI%)Jp>DNi=EE zR^}&Zb%)lL8DHdnE;@Xrs7{Q`z)tJOFMlA5PKF*|KG)x}4VuaoF$SuWw&m(J8@1|8 zUM|~8B*j7{=4bg?6YNV(Y_!_W%J!~R$471^ofIkIzET~j*r5Mjlu?*7Es2i9;oQbI z#GY42ro;)NcUPAR#ocbty_xX5(yL2p-v=hQ`Ak`56OVIS zSAym~_O!12h*Cd__CYl`plx?AQw*&`?#{Em{xe^{M|GZK=_<_U@+!kybWz6`8-Hrj zYNSkLqFkeZqu8q|?xZ!O1C#?DdsVa3sMj`jouW0ho^7%AwMJ9IKOQQU6pQHn4Lgu7 zD3QJO&$pkG<>jxTc+WWyMyKwgP0PePZLD?k=or5|U^T0~J3vVK8(cuQ;#jlUe#+`6 zHf%Q6DvNKJ)ajyh@gDP)&f5L3|Cx{bD(5Um5m)(R4?xM$<`~+{iEurmeO)J2T*f{{ zj(7=DuelaSBetE!^Z3O->N(QE%TSH^sLz)c#E`y7U8{FJk7D9q>;Nyo8ifGYJ7F(1 zQd$m9rLh{bnJk8zvkrwd6Q;(}cp%sK^WXCyM6Z^A$Zrc@m$5IX@iUQ)C?j)D7MlWQM|I_9UMW@y)3-ywxpBH1x$(PkL}?%?EE zuqyNaFe7=#_=TGCv)uuq6=eDF^U{*V^b+_YOj&5PZT4*DMN_eEt-p8MYlUBk?B!Od zT&F^M;3IO*&mT$g$A3Efl%4OIs}$NsS1#YJ%DHu-6qcL(lwwss(yCjr5b6Kqcj6gJ zbV@QYQZ^Nx~%CoAh)FHwwjsTZv(xao zXBvV34yfF{v)W7_BeibocsrZh4Cvm5-+Etax0_|SF(^CP@Ww5SV%GuiJB7>|!W|g2 zlYkvW#9zlHWLh9y4sNfvc@_TJ-g|VbeA0qXS!U`a^{HaaDxI?MvZ*Y zBT2?gum?3>aCwW(2W_k%b_A30w)Br2%AAZJ>@w$5kM-_k9+B-lDaho->1vIF7NF5J zCJGEEm-dFgU*9-96faaFx=45(Cfol3oaz@~S9Vfo- zwkgSb=#84!a~kAKr($(|`@{5x>Js^K?By@^F-ql6DR%QtU8?E{YtQQkh&l_PF%~8x zC`i_4XImBfD`ZCCZV|j!n3N>!EhYYU`Bf>9Q0A5SWc({Nt134iS^~upqEEO2M>bmr zet=11a?ZMxUd#K$;qCVd>mMMsg$QQ@adBz>5U@rqQ!sYHi(ZoI`{KW3o9AEK5;X_ z`|`h{ev6epJM)+K8IPRXIwxceP8}v^0S2UQBqdysPC5{Sg>I4ptt>3yo6SWR{LYiO z&gIP;#$E_&45xClVY%f=PrBUFV*Q+jg2D1=03V@@n0g&}i(c@p`aA8-vkRQnR#c>- zQ_606k$%zgi-qm}`Qd=2DC_O_3p)egq5~n^r(We&jsp99-GK&t*-F{1nc1sGVUZR} zxniWo!I~{lJ~F@7lstYqAkh;(y_?BNfVoT|ohF&RXBh9fq{j0P z8I~ZAgoicGFerv+A%awr(u{4O+~gmCj2newYoBDuvT zW~Df4W|W(ULqTO~i;nvXSqT?;_ntb=!rB;Ng2M#aRA5Or%WtBectMs#a&6*0uPE&J zy^R#NZa=YDvQV)wIdC?Go6Z}P&f+Y3UwFX4CKn2~UaeFaVisMv)OFTSL=&*wbg@slAF(p8OOiae>9TT8a+B2K?N z^|qU7p|Z&@^{-JnkWfiN30WEP=!|xFsP^Vw<#282r|i~Db~oL$!!8n12B^9B-X!Z^ zyRyruXoa)R^GO7>m&1#IekGe?x= z0*!`i_U@fnSoKCcy{LacH9D=BBPgp=Wk=~m!#Htz4->7`ySzAx`ru&M;GHKDxti~ ze%X)t&%$?`JD+un>X9$BN?Lt>Y< z?z>{S^Tv4mVlbTKPg2Qlk`P=y<0xQ6&dU{l^4nPp?;~x|w$H|v6@1!)Sc>Sq>(Jme zD*1(%(Hs>5Q0-b_nd4u1%`THA_%ciXcUyI4B9lm6!}{jnh~`&2@*0aVRgXn-5Jo3m zor@^gR zxk1h5y#anG%eiO0x@kf!@61+-DZQJlpw~GPE?(2GHg49Mdt_AjX@_kmc* zAD(J*GQmai^!P^D?#(9tS--lsTXn9<0OmYfapKV-(Cj!XA0q)7nYtRt4qauw?~i;S zC>>}4R72-yu&RCWb?4){GJ*?SkC#H{!E0OJ6(&zDCytnTe9z5wzG34Z(i*4Jf5f=` z)6CuN(?OlldgkkLUo1K>jjK^p` z%Dr#>7-k5h(A~&jR%tXCg__*>E<1~kQEZjnc;|EZ?bcfVe6gg(M(~x^ueJmH&Q;)r z@nYtT)A|5jLnGmd!=U{*RSD8`Mwjf`V}r$Yi}qzwqfM2=A0d${gDL#Jfs)RNUbD>a za??G!qzb-~5oHu?KN9Y#9K!9l@NhWa`(35JrV=+R7W?^iWK>Fp@r(p5x#@6Omkbp) zD|(6%eI`-?A$$=jy&`=M#%uSrHg|a9$CL@}x*~33S)19SnK5kUft*G zr!OQLJt;$}P+qq{3dZ6I#^Slyr1oY}a|Cft24d0X&=-OQ5bnNDXpbw+U;MOE8+Z%z zt|KKW*JOzI6f85m6$Rcw*hQ7>&d>%PxX|TrI2OvUiIQ)xG`WQ-=GdXw3nYu(sicL8?~;Bf5h15AeriWIw2u?D|NCIpDZoR zl>J(zn~ysV*`#og(vT#=wSVNeC?3Ntkf+iUz|v&(el)eG4=GM@l9hSi66?OCFEuna zSxk07LT(&LUkyA88F60H2^XT;<6h`3AKSUC0_JRWbm54fqo^{+xMbch@E@x2(;nJw2_M1Y{1;AiX8vMd>oaK>^JnaIbsB| zcSgr7CzM6oLM3g=IEtNEOPy1MrfuA`1bM@1K*q5sh-jhE{|66JzIhh{NTwkd1k|C2Z$nK%a~+ zvwIe*rvqUO=eQrYSz{bhVtnPRR+t^SkqJDRRSHrPJ}OCO(FQS3P3$#N$ap50kJf%D zc%6*5Y^<1_et3Mbyv(`_{u6#<+(hw7*Ph>?r1LYfuT@{HpFf~)lPKAEA(H0SpX&$8 zDuS89Ogr9IY;d09qw%ST%)K!QlSb82$_cXX9{OMUqa!P$zT-3OwV|$3rf|mK%&U^; z4>1OU^2wv$v^`xrUJgXHubw|-U|rlc%D5%uON%9E*;n1~POVo*uMI04X5?m|)RM6t zy~cOO@ca03+l|SQE^3lgt(|fn_orm;1bBz|D++7n^hJJqSVysiCa1h-igXF(6GqGq zD>84p3P%VgsYIiwxN`yu*|0_V)N+o2y2=w0rTmL$Ju;Wy2}LZmaHu6FG7{2F1iAU5 zEMEe!q{ueM4(%{)m*#q>vu8E7YcRp4a8S$zbW+&;0EqwbpT(Gxsa*hG#N;E11bbU` z328ae{I0~N@DAF=(NJe9<{QCdP4ukSMPWa$UxtnQYCrm5v50|#RX{Xpm{nQR)6)dVJXA9H4^VnKH^C!vi z(h#u(2$6$0#1bTH(0o149Ks>7=X)-vFu#I?981vK$DQATrx7KqP z&sI(4x$AdQDpRA6rPS@^m3@Zbem3~L-|oz~7KJ3z`JB)b(BMdq$n3ekam4sdH@YU<+1 z3mqZ87%3m>+BL}EzO*K23rZ25dqwj2`>E6cVmdo|^U+7)0e{TPY1bVxLJJkJ9Oo~z zjpFjzF-pt7Lxh3oeZ$4@Xd7`?xvf4%MOWA#SNXVr|NS^qs%S`vXML%fOYB&wey)A7 z@XFaL?xVCuEilMl9*gti0tddb)qQcV*2O>GeH)6{qg@C>e6KUCttli#!PhV!*hQEN zxf8X)vKZ$YgYc-4IM3d(#BYgnI6fGATfZ0us`{A+jl?(kr%;>n`IN zv!zOGvVmH%vN8VtjZKec3H3W+q!08WtVUe7AiyJdS%Nuod3uEuWj=%vIzIbbzig!_ ztKYtT`11EX*OxD}a;=Jj+ANCB+`C`+)ym>|iT82on?o`Q0O{FR09VPouM53jxBoq0 z^5vMuT@=hW54L+?_o%CP)31>&!ChMZc-vD?GzNG;C`JXMI#FG{I7ULR#|ggio!g6d zX~anV92`PQlz)%Nj&{3+#r?d+w?fYEvqTvBYRwW<)^l*rcPU^z(5gvy=_s%r|0)<^ zFwW9YmJi6e9c5VdQYlHrX**=by+= zWkM;*OV;{j(Y$@S5n{hj5={wYZUF5dRqtdE+r{#cA7nxFwLDoW#&^{#Vd4|fBdNMG z-@R=1d^6)|JuF~sGky#o;0*la0wnNx2u&H;QeiNf4W0Zbr|rq{&7`2x0HE)zQXzfw z0b;yo9WU%Kb@n~)&vzyxp9tccuiUTb-{fAPx7^^y2;I|A8`ArtB?}_ow&@a(QejDm z>4-eB$Q^Z_%&vk&&18m*E1(hpdc;b1-Ji?a&-Lqsg5Z}oQ)+Osv-SbwC6K1?v^t~J z>3jVK8bgL&Sbk^1aCu(jcjA&wiisqvNj02OLk9@CgBFM2UWZ_$J$Vrv@yBsFxLyD^ zGvsn|Hvy|$JGy3m8i0m?HR$GYvl#(-)HtqCbDXnQ8m)rnxt!sS3a;1N3S%fc=&ZJ~ zlstl#`bbv6AF!HX_Is?hM4OFBfTZ?n-{%wv?TO%x&R&>WheG))=nr7fR*Ot|_R)SM zr1F{xVf!?2f%}0Jkhq=OB78)200}~V0byvNrL@=ETHZ%qkmOpwQo{8&4hQ4s=c+pt z4(;>>DSEz8L|4>&*!fWl6f?Xkzh!Hn(QjbB&?ZOVzm6KB5+X_$YEQ;R7sK|S6EXu0 z0;3YB#Lz!F5r0g`VUER1hepKs$$$b@Lo-EXhso6~l1TJ<^aF|prOXfdoEi1aHF>k9 zDf%;ZjY?oW>*XvqH9&&Ge1V*vH@DrmGVphP#rU(_zdQo9JXNQsG$mG!Sxn!|Jhm1( zV}FBp-)d-=?O>1GHu$PZS`p3BC;5m*!p0cYiR-+d@FBk?4*p(2dD`CMx38t{h;Qg& zfrfPIfXC9i&EFt_F6*$I1>?`MB`e@ktg&R#yBP3&`yqV@ZuY7PYir|)E1NsYzyuUQ z*vAJz#vQN@CWTqBPX@FpBdasq@OurAY@sdzi|a7;5|HTE+OSgVx)JFw6i0wSj-=!9 zO6-Py@W?+r<5x!W4&p&a)c&tD(bUA1fQKP_Wx~Ex6)v1b&_AD^5G)8U7QODb`&!F$ z)#WYc#CE`e=EI2gj}ym((l@@ytHi zQnq5f*5fsaxYI#@gip0T6vK5pg2`|Bph=(6EZPmNQ~87pJ}yu&3%h7rUXwEmZDZ%8 z*5oZq_vqDMC-PaM0ytpHC>Zz;|FB8KENTV*PBT0V$=OcMhR;*uUy*Ml6uoe$AH?nY zDjuFU9Zg;pH!qILJ&binaKTpfjQSHD6BoVkLq!*9aRUTnnKOdD8w+SlIsm&PZO@JM z@E3OiTh1jALd%a@|F)8Q)ci$G!`3qg|FH2d?&=Bb>AJNEOprk#EwmeoU)v@yR_W5N zhz_TWcy`r}@#%My)3qP=8Gx7&rr5Z7tqTni1Dmu zw4wG0IU{Bw@{gu7-BPo^{PRPtYnOwRrT4m#{>nc09zt?(w00&3b~+I#lFOvj_9Zk7J; zfjGkn)-ZkRYMl38Tc>I#SCB74d&c+!|I>Ut@_34Bw;B!owT4EQqWvHciuLD5L`913NvE@NE6P6^k8$g3b zlPK3={$8@PXQ_cF$gdz4Ep<7^HeY>!Fg_o9?!^GecO{q{k+splTOdmP3Uno!7+(WK z0;Z51!B(Zw;L@Hv^rSf4j(9$PJ5^(szfB3Fb;?V83!7>@$s0Zje$3s)5P~ z^yhB;gUP5bat_c(z2f_0;f}!&tEOeQH)&={e7MvFXf-tPG>FB0&ivV{GiS~Y9i}!o zjB0qD6}Sr102V=>IXwW#gAS%E@H7fbqN3)(4!$|J-o@r@g&6Mey*7L{&(PWZ(Jf z`3EOLPurFtsvUOBX3JB5;Qjuhzg!s|rxK3$fEr|9zZ-#b$IJHv@p?WVtlJ4ePl^~6 zP8elm1+LCSjK1F8c9{Ab(2X6W(R)UC8u7--0ZS5_4UkAN@}YkNP$_c zAAb`*Z)h`Jc@H??_1mypmG$PPkyz<&^7aBv$Zg1%0x8<|;8I=}(`~ZpG0OPV2|f9{ zhEnbInhIs}Gpg?RVbh@qtutT%f*dzU-a;8cHm`sBM}INl-YUAU#(S4Xl5aF42-3dJAzY4iR9< z$gN*|n!ji<4&>EUdO2Ai&j!Kjlsi z9UFgyOBXA}I{1A;tOP3m+Oz0}-{VZ0g@9Rk|?q{Oqy$F>7zEffE2r4#6JtpZBV%16imHd9%^ZW z&T1TT@yb0;e!7rJm>JV7>L+yX=%W#ahvtzqTDk7=VF^>aVPs(%6Y$+(hd3!nSRI`loD)x^6^3bc5Q2ysyhU zdyNvDP%lwoql+LD`%P|qqI|x|Iu%2SXfHn(8kGX&ys%e&Zfzjbe~|4xU$Q$n_bWpJ zAZBpk#P{(r@Ehj)oi7cH_g{eq3IS6$nm>i-l8C0uHqJn4zF|$hS890gM78{iWtWNc ziQhJlMI4@L+4GR~eYley3l3=1tDn3E7R7f#J?f|BU%}7nAKYAF?JclkRM~s%%PjqN zzoo$mvdb&ZBq4@GS$9n)-v;SrZz7b$DE{qAKaW*>xM!VUdzu0VRF zK5Z|Ny|S z^?NGk%!yeDAnoZ>epz_A8RvNS21;b$8iv&^}!le<_USvbl7|6Klr5xIB7-!} z+bHfCUmIIp$UWAq1jqvM_)3t*WNzvAwUnk6?_X0PCsPSKep3xnZC}RY(^oCKz8jxv zR=X;UkT#o)$?=21D+eIiB&|?k;qK?RW*Is5HPsBloekcIH@ve3qR1onag@!MsY#KV z{71h&+{#7;Uyz z7^HF6FUk>+v#>tPWM%*p5xSjluG+kLX*K8W z-L<(bY3@cTT#Y>RQ&(yni;LEG+2mycTTZ)adCI*bolF=egvR2E6xCrmt&)3T%JCp8 zgE4t^*Wc~a!d3=v6wN9mlqJlqkEe6s=kQ}ei}N&IHp06Sy~EsL3+h;V$NnEr=N-^g z(*6C%bywF0Dk>mt6#*3y0@6!%Rf^IU=`}(Sln$YnuqskR5RsyktRg5iMtV!6CG?1t z(6bOo=%IxW(ta0r-}letCNuZmne&}5CX>k# z`O^UiYwCWgi2PxZs3(i>>KP&`19gq5RrlBX!pnV@9LMQq!M{Biss!j_xt^=F&2+o> zTb=nsz4>Xw7-4CIJ^M4GF90AjG`D2cH}K;zL@LXwxJM*QDJ)W_cHYDZKOyBQGMRh} zx!pZR6>S&FdMv6bcsa=xa4aD<7I8cc)HQn(ONw zt~1ObWJk-`F4-=bpVKH5hJkJvM_VT3eAw=@OFb6&NCC@DmbjiDdh&o&mPtEHh+%arJ= zu_Sl)p~g6KN1#$ElA>Qsr6hRM_3+@wT~1|}qOEt$x0+RZ7|sYSwV+eh$fn}^(^LTG z290#?-EKK3s`uRLh#(3Ua#w{!H8`cAJeNz!w`?wv*;~o$eZy1~@OKe_kOYMli?He9 z1eF>%qka{FWWKepi&$};_68Lb?-7)E?yJj69z0dpmx;cVV%gxC{5n-Nnse@+a|+?D z`EqhD)V|c*iF)&V9T~1C+N6b8Q&%LlQMjA~Ov4J*zQuQ1Wfy=v)cWDeNg_kTUk=!P zg7K<6N~6B$c0LS%cR5PCMBQNxY(>YZkPYR2aAQV`L%FbX$|R)&j7-f>S*=bKw!TP{ zv>rNbjYukKHebQgFW+$)GCkG==I=GdMGSyN*^pKq^W+q{i{{V(_N+p-Xr3JbAxfaU z;ztLBup{2S@RfbTdAKs}of%+YIol6$`nzG>esVR;NnqhER7n|7h4>UG1o0V#|$OXQ*z~)c6Q#;VBma^#4Bk{-u(~62i%I6 zj!og28{`V^74ht-pj)Uz#337Y7Xy9p`Ihm~NnGX+co>fT@% zjqejD9r^Ixouqq6zLFQ1`O~0Rs!xTFp7ZWo?%XrZz+)V;6*L!J!>BW=BtIyis7fSa zFFYZq9GF14YMD>Tv0x2llKI^+knQr<^hKc)-Ra_d>kopW&qFUmH?3tD{zsgpr!Rgn zr`U&ebMGRbB03qZk^p{7bsBqXD1Bt4#5bN=_|KZE~gRk!!#hoYB z3IM5S+Wt9}9;0Ev4d=VWWm~epueQVV&L5~^PDBmX&b)87^$ZH>m~ith)nZx+y|Z(> zHjp{IK|V>i%P>Gpzl0-Q<=XaPclNY|W;-Lsxo1XWj)Dr-5-wb~U88I6i`ur2697yI zRaD-RN^+u{^shhbDBQ0gKu=a;n0$~8nA|cK;QNZhh8;XA6>SMNqHL4>@2@~p8j>b~ z?D>5wV|>pWOq!vuo_Yo*g`Ur(2RSf9c*>!_v4bnqWDq67)J4i*(&FqVM2USSE32+Q zRH*t~n+I=x-6; zQ>1H60S!RqqVM{K$>aco5=b>Ap!W3&w6;IRuI1}#zdVxFLRanHQ43enTc0kg4p3=@@^I+S?_foxi+@vL{k?C@zSCn-fLfju$B(_aDLvjKbp1_UJTQsj8 zuI;?&k2nl_GUFWUu0^IOOFV}Xekr;^@TazRPH8t!y@1v?_C(3s3-uj^@re9U} ziBj8*1!Cy_NIih|QX$6hfAlrYz-#*X;17Jv=mh-rpwnT@XcJHQ2MwmCmZUOaW2WIO zA0hh|07i@g%Vg}Joi!zDGyl(jfiX2|qzRW_p_Qo(1}X<-p8tH3>M&_0V%eUTalk5V zeOS@&f0W#p-P0aORya_l0~x9+g6lq=(h`nv-i`*CvJvEwcQfik^&u$r-;wNnmo#5buS3F?)~BR&ayUrSW{97(>VLmYo}D zs*m<;ddv6Z>hnfp^gM1lv}>tTm!Bp=O*lbTp-KU+M(cKQ+PsX}g_KlqEXiaU&u#r z_kiT@wWacp`Wl9f?^LShC4Igif+4v>~Dvqx~y1ql?n;}rj(s;W!4|;n<{c({bLfAYguLP=*i*Sy?I}Dk* z>vhmBZ}y%kSiHS6fBFDASY?D7Rf6AfhqFop^fl(4Py~tKWEpd*t$((QyP4?=yn`_5hC3&G<$(Nj z)~#swa?aM9jLz@ zEi|OE-<0OE>g3rV8RD!=?`^;qWzB1cSVp=2wRc+O~lgg-~qB=ffaZx zwD!QFAGzkkm7n+51jW{xEyTPJfzTi{CmtBN(9AFHVjlM$#c=I`H}AgC&sk~S_$Ry# z(3V|~v4-#1b*N=8;7tR;#jzD`9SMTiS5$wyoDGCSQ~hXXk~4m@L-F0cDYd{?w=Iv8 z(Dzoagy!Lonf|6ekTN9u|$hv9=z*H~ssuU!MM4cv9rIBWr)3JT1gK zYG7n!@=^;ue5mT=-$a^+?$Y{F4H_LB?fPHe&>7jyvuDA?-L8e`_AqjQ6Qz4kOVB0x&&ZM;F;-B+T zuFz&LC*1A`3Q?pXi2n@qoG5&Btv1>zH=4(iGvtO*2=7xDor2+u>T?7`1SDyr4)cS$hf`S9;_a9Kn@Xx#l%kHUJ ziq0o=FD4DP-&szrBY#gFdJp%$B{~VlZ`8Q=ah^c$aZdp90%Cj#&8VZm!Nchs>o+T9pm?+l)W6u&{I0Nc^BC-jdc1B(rJy3<2l)p~1_fBjLUB5X z*;0gk8XSDx9Ce>NbSE_vgEJC`207M<;b*$Y7OZR9cBMUzZzurtH7C$f0P&;N_6H+6 zp&lJ-lx0*}&(OlKe1z%L+a7*&I7~#HwDs%9$qP40HyCfKyZ4#l!Q^i*&QOAGEDePp zw1~p48z6COy3j`}>&^TMm}VlI_ZY(Ph`VGmThjIti&NqB1jJfOm`OmzA;yq}b(Z+Y zg!fez=wq}@sNl^BE|3y%+AiVp3!*N6AlkW$UA<23p!aCTkkQrM^r$JV4?KssBBAuC z6X%f~C~;nYy&mC$GVbVQY`&7*08y}kP8F9z=$&hz$=WoKM?^^e*J3GoN2T?h-$eL$ z4vhAXr8m>pGZkwP`F$W?W``DTE8gig)xpVS7J}@UVxu=?5;nY#2{Hv|9re5lhFmhI z#!ytoR#V zAc91b!_vw!z}TEo8D;W3LRb;q|NMxRM(JJ0*0voE{ERQ3%?S3rz_&IRMi+WRzR&m^ zgiOMYllh*?wJH$xIo?<(EU>C`e>w*s*Qj`|V8NkPo7K}RZxCyJnH+0Vd~M<4K9IfV zZN#eQjm#1NJo-Jtj6KSy3I^r%Vv7LwaLdEUYh>I2a`H#Dmu+0#g)+PJCFi zf1{GJPk6v|it~JO9YnPEImyqcrzv!lt-k<}oz6|Tk78sMp_p|79qDGQd2>ORcx)!-oMzplAMb$)FE^=Z zBx1*k7N0IM7OmVXQ7IkwCO7+M{RxvqP}{fG*@Y5h+4>>Yi92Zk%9_jkWkLfza1$U+ z+2YhO$fr2R1X(D%H;2`FJ~nu`zk%h<1E$`G;F@#cS`teHzL!Srb#V#6Uin*o+FTTUrExpQ(>m?u@Gh%k7$c3^ zQmfa{Ofek=(f08ZXZ$5s^pfcD81?U{c{$E4^~@rz z%87&nDO=I&$xYV@h5VrSqAHF#i;d~Ag>{c2v_NCW4K9AP=8>lxz(KE^1`Q6rb|4nbkpeA{YbxYOyJ zWL6KzD|dy2-Os>8^IKHf_Bwx1zSV(H1lRC2TSxYzc+ynv994fhugi4|d_6GPP>OVuk8Z?zI_jupF#f`DjGGna)FpQwQKv9lcQ5Ue=~q+ZZ&{$w_|%P)0Zj}oQ%-~ zRfPp0fd_;QgX-lybxGns+3{NjkflsEAX*YhQ-)hUr{q|@pl#Zl@7sfz$I@ErSK@1g z(zS4BeNSo{45VDcmdXg(fi>sfJRwrEuQBj8E4^@FTA1N=WH$_w2v-)J%+{f@a`jS1 zR8Knwz0#NonA7YW;1896Rf63*I>q_9vjj@cmDPs`|Bnk*kQm+|S-Z~rH`-`rWb@i? zS#JVL^tyK}q;lLfFgZc$STbr4t_qbTpYX1u*jw!vF46 z-dnPz#dw4sLpXjuV`#8wmYk$sH@x{AguNbZJ-R?jxY-dC``K)Wl5WS1UcQ2#Omh@# zz+g2*v|sI$fs$T;yo+iuD_1JZ)9Nk2>cN^W1M{N3Z8`PLc=X*zWqy?^Ex51Q8kGWu z8dV9A&|e{dL-JBf7Zj)Z9hkM;so-dcWDL0!AlAg7)KOaAhCcJINYss2gq!-t_yB{T z$)&D9-n0>Js}mC(u;<&}*)yh`7NZt;9o%o6BSg6pYXKxv@YjU#(h@*uL+G0=T;VBnJ6ua+MA>b>iFiOb5xSb%lM}Mlc?pq}-RhsVyBV&jf&=QY$yAIP zhKMOkV(AhO8?5Z^8qjN#x4BmrM$MQFVt1M2h z>n>lU5kv`_w-YX0icLf$g{v;fF0;7F6T3D6t6d4xmvG`6y)2w2}R>Cwt zZyVA+Lhp3uOJrbTTulVLZ&um3nN2e9-3+sP?vm7#O3p?l?qSZ5LOC$$TF}(yox!KG z%i(3&n!Z}<^HG0up2J9q+Y7i7m{a-pw9oS)dtx-UYyG~<)Jmhba;+kw+m-r4afH>D zNLhD$1AV1!roUxG<2@ag7$R~MU!YCs7d)4ZXHzf2q>vj5v8uQyiX+6^(0v6NIW1bO z`#)&Hnj$J6v33GraMm3^^0?-f2e#=#N$zBAMB2xFmjOF*;ij1{%}8WSOKg)fPHO&2 zZ1!Qod-Edf6uk^r^=)dKoTD2%Gnd;Kp2eSTZc7==1s=2?sxJRHp?yr=wU_DcycN>lh^78J3N*9(OlRVm{-1{!Q?+%9`|(?6dwj16p1J?O^G7<4cKz>2*H^>KhlJjb ziJVPBiv<35MQ^U-rN~iW)>A+tM?>Wgxwj$-0=Gb$%m!zEqh`#skQrUoy<$F$?_I$K zd(&Y&@-}2;wPhm8w!$HV{yX}E%l=;9o3za+9X;d0Q=85=*N6?pCE44Odoh=soG;+Z&-1x}(Z}0FT{ejQ#vqC!<^GLbZ(qf;YZxM}%g~R$ZZ|&fag3-iHEss#>G=V7`wZ zLSo=^EC7M~6)HSmrPv}J^4-Rc8JWp6Tsi7MT7I-LhW!Hvt$wwzjL%tF_U0Ao3g+xa zo)qhR)=1u)5Z0dX0h|sgDh4SJG}Z4%36#y&rl-Xy;BCi?)(`!$6802gP)w`B+ z(>%XA-*{8+b(%pwX2G+M2FQqjOu`~g^+D{FwzJ(TZq4B9_|J=D*@ZpO1)LTB^X|h8 z3_2xQG$e*(5I#BSQ`3tceKL_rh*m#Gnih2w#h0&bcKAJ>7%dNXGZFZD5{|q(sz<$o zNV^hxQaym-5s%Mx%vru(sAp8@rW(_#=zM2<%Q+PvJPS)_$(C2XZA&> zh<6J@$ajUVFxWom^da_A+Y8mK8uePvk%y4PJ=gLpsEtR!_T=smk*1~+jW$dKkyEcQ zA^C=2uO|av=tbpO1`2fU9X!@a!ngZcCs= z5?T7D>!{?0u~NmmZV0i4igggef&A11l{BLM+768z3q0@rXhFVt?scEPupzZ+xk)*M z8B^vAk2c1tGq4YIEwrG$#GEmK6P4!zt;>Cf`%TYVhG=$7Sz`cM9UM(~dKT+(In+tx zlU_(f`uu~4d+@>@^y+@GD}>bm4;ihe01QJ8B9-uu$=a-w)yc#g__7B*5 zWo)8QG z?u>u({7H_X+vw7nrV_3%qr)fAMw24myN@ zv_6&cSWo8zCZ6f}&uTfIXEfO6o~sCE=W>BPE(|34g4$J+uCu!~FqW+3Q4w^#C<;TC zlzQat&UHFlSK2GIT+Ut|siZ79V4f-9u4UfI$DDUPDSyXh6?1i|j?hNuzvwEs_$92& zitSUqR<&nk1z$H!4+(3Fa*NfkA+UFvJnvK0d>+Pm5eL6*4SMwYKTh@6^)N5r$8#Fg zLqFMmzscYmZtgkwPQV^@R+qD1yPK!!@rz9nNQ1)SX-w4HRfxF$z8&-LjbhyHPa`~u zP^Zo~xQ>rk5M1+|r^pv{&HhfAZSI2Yb%B%x#~>3{$Sojs#h#lslopRU#RA|=bV%+WsQd*EA%8zx9|ZzYR^$5vG^ zFpEIEn^#EH9sKa-i(lHt)=cqJXRP7VqZ8Uti6IYNX}8|A%!EK2LhA zFUHEWiLl+=72*|nS7OVbgyw;wH3u$k^JHm+Oz*FVU0^1r%-dF~H|=Ip`Sd51U60Uc zxba}a!@lOrYMCd7JB6c8RPbi)bk5*A(m3&XX-?W~JNL9$)|Wf@WL1+>tm}AWF)9yI z*>(!wmpgDNdnqhWiLfONtPns4RBucG-95kRiHfW&^(xGyUv=d{og}Q!!G&vd1?=i^ z>8#>e^BBjs47x6-lCr{-n)M8+s_I`B%U-E3>()$Nx#*OwHBf7i`*s0ZQ0}b&DUV3q zOwf-#(2Djf9av!8spyJSgY;-w&m5`Fcp2P~$7M8(Zwz70{w~leSzv^17jg7uY}Rfr zGfP3}WG9q&>D1#2xiGgJ^CYPTkI|@rn~$jV_8hZtsXGi+es`a#c3MqZEa;}2boSM) zzrtOK+>cS0H_uJB3^E2!4PJc(6}Tl|P%n1s%BYCEqvp#I+qS9b4AA`VQ%y%$7@*6p z#{0r$c)|viol$Kcx86MN%8vA0ol=n$d? zaLzHvT>tgeC94%i&%HgEvo|45S}#akd;T@pC4bv?&8}}w1L%owCQw9=Pq0iv$3G^& zJP(&oYS8(pTU~!cZ)fO!Rzn`={r?n%!509oT;I^kic<7BsC;*~qbAc77!vM17Kyrg z0Ii!jZvHWHZ6Fx?@Vg1iFe+LSuMM2~XY_OTj__75s%a=3y(h(;`=FS1WJo!0K~ zL)!2&Qk7Uy{CeM4e*n|D!^Vv6QEJgFxxx+N?DBUds{Q{af4D4Xfq>M)J(T%mSwIhDYYC_FYecqVtadmh1uPoICl3Ro3A!? zo#j+V-P{{d38Q_OFt=D68s8FgpzRwRsi~WvT|^(~o{8i|e1CzY?`AE@&EFk8>O6S$ zi(!E66$mCgL$2DM==Yi6KYRs`hZ3w!7H!F6^P;s}Xo&7a<#RJ@nk|+AN3bgL#+aQh zb@bvHdYS^C3ySjZd%7asoZc9LJTE4m)L&ej>(;&f#=;%)PA%$2n**lJO>R~UJS%C)q(`gv&eu_7_&8`g3A>CW9lBPr@tgtPk2z&5sqJdN_bWO+FG4}8EYLK zG|GE?N$Z>hQoMcCw;!&MB`BMGk5itMTr`)Ys%Y6ih<~?cN*y>gsQMi18bkP+hGw>- z5U~J!KH0f17I@}2@|`~$&so|`7uf9X|EjXNeWDVh^;hGq{#g%HTBiu^yHZ-J ziY)H+-t;)I+dFR#&#D*IL3!@I{&$u?q+-y9GpMa_fGY~e2UtCFzCLn6Sm)|i zx5SyO#nGJ*kLcgI%hVc_`cbz={B=L`>*^qJLARp5m zr}?Sml{JI{80x*CSv@uKIZN;^?Z6vT=eKg@Z7rhtk09s4cz@f@bt~5edJPfW0R8S%GuAx26y@L!O z2>uyRJPH)t@U0y7)d7#Yh+j`bAr7hvxqK^3qjH9rdV}N^d+`+h2o(0tp7vLvC_hxB z%8YmEBEnY>noVP_Po>zFqnDb%6>BL@DvAxbX6+#V2bG+F6_N%vv!Bbt8Q2<3wog3t z*%oc@K7WRA2h+av&>dc`Nlm$MIpk^6`aJ76NrPpaK4qF8q_Hy#6MjQY(}|j8JeYQ@ zGe`ACT(X7;u=iVlO&q%mp8L-8F=SIWrCJu^%@A+=7{kbn`zp+|8+O;+AgZwQagord zj(1=^D~%F_&st_l=#>>5BVJhZ-oKsq`Kb(wuq|YTX81WN(lLsY%yI4wuoS|#TXn2J z(Z{t9=4kgFk~;iJ_&wJYl7vdsKsu45Ke5mbm3FgZ79YbEx9RqZuj&l6`O<7T6v5Le zd9`e-6OA3KcbS3aP9T4UN!=|(`obmJEft-Xq>?+l(_zZqzhy02?byLiMsVG?A^3$z zS0mHesxRwju=Q)-Buw>sLx8;&YYH^gKt=>##VHp^beGLGoX8wRy>A_(s(9#iiCg=? z*Zmp{Db#Au)y*B_P7&(o-4!FhSUJurBD}<|-MZU>d3WeOCt$wHPKus%J?sjG^eG6R zS-v&{oK-fwh=-p$g|Cgr6rhv)^X(*>E+7Q?N2Dz4(F zG*ZSVriP`hpq_@oB3;Y8##NGzsaGLfPq6EOViaq8QZTk#Z)0x zunBc!RY7YM+3ZQpx6$FNlUE`n5{ z^=;V>ZDldno@#Dd*11RTSfUvVRxIe*C>CJ?(Z*KJ5#3f zMYi|rLK};EBl-b=Vl(}(m>7jpkEu`4ZB2kCjN`whygdQ8{(%4IZuI3+O}*Fk%lG?h zu$nqz-HbNjELM5IDDAW9a@kv}5VKgD+B)_z8)HKB{8G|tP2l|RIi_`N_&3KYi4#@_LX!NV zWQvuv;{O)*v~}#^s`yDE9woYNBI#$~cXpdfncDnMyH?MDOXcA?J%J2#S0I0n-NTCZ z?NA*np>7Q|N)Vug!#V6jm9wc@YN)Ez`XlTo3(#a@jk*{sY+mn`ch^BlN;%aLygAfh zYWj-E|NHDgp<7HBUIcDJ_Lm!C+f0k)F}GVt0(HCQ41p7(I9?MF7|{m9uw&jrJxEH% zO-=Pd(K10Te-n$Eiq=|IryUwj|ERJgjpcm!W3T5_j2`jk-g*?(Q{jP7*CuR<+JS^! zcpD48X$x(jNdf}}=JV8j{I^KrC!pgGCiT}V7b#tZ3#xCR> z`|+8YK`Cj%BT7Tc!3%O&YVw^ft0C&xuWYnQJ=r|bFHEV_bWPjIeoyI-oeY|ReBrqz z5sx3OF(}J5%>7&o-ePs>t(IBEQ0BdySOxQ55WOaPn%eSM^gywTeE%<5U7VZ~f&G(S zb9V-N6+Ha{!;~FT`!<8F5Xgwnm;7(IF2179+1r2I?3D6tRDp+C5tqoBcI(Iic0Hcq z!rqKng@_$kT7l{sj(uJmPar$ES3;5l?tFYdWJ>jKSlH99fIv0jp=!d!p1||iy$n;Y z-4+XOe!AVd5iQ1v5?LoTS?#i(Slv1{3W}GDb~P*aNCbsyM1mX;!!iin(Kz|M?#;T( znw0x1uB(#~Qq#ir>Jr}Rdpsj-Gk)VDsfoM)W}`{B@fI*noPuIkMhVUq7!QfFXoKY( z=*7NI#(P@RAJR$;b8(W{D~v#dHTOE-Y{q!`LRPXUXtu-(3Y?dlhED^tRe4e;f#w3y zUN+^rNhyb31+9yFCV}F`YDzs#aGtBFql%I(hTQrO4fVnTN?$Q9-V68LyeSM*H_a~w zr4=JI)k;qMywCRU)p8SOrU4-Y%8IrY%B4A{!)`l;SDJHttPq+r5bx{wuRZ>GKk{3#d@*~#?H?S*l zDw<5@-r$8;X{?BXeiiBFM(~X}v_4+MapFz5VTa#pFMA&p) z(9{8Db-Wn$+&}FI)Uh4N*tv3kej+ENEJ$3=1*Xu~{FZztJ@R&Dm2AYCPj7ej#v>$4 z$MsnNTGBdZh;B_z?Gd$w_OA7AzS;jYzWzqEB^UmL1NoUIn%9V2u;sY6w{|-8KN-=E z30&wEZgT49ch)wDM${NfwC6^ui{wIj)m~vtTKUefRkR+(#90EcP#{%7zgC*U3Klj1 zXaSHHWkMV>bH={6BKtpU*7OXy>DCgw3I;rhU!LE~op_-@A`E}|@5hzBqZ>sHRAt~| z{&Uy1Sfsn-a`uWcF6qFh0P-R@c8^Y_Jm{TC`R{X-2JqNWKJM;+rCUqDPEkf41Fj5^ z0l}v)j$);b!qRT?;{JI(*3wwk!u0j%!|H{VCD4a?=67@ zcTW#1W;?514qkvOq1$TFu3rep%t<1!v|1;eQ_Ar3+`<=T>aw9|10?@9<;rYtD}dqM z`~hNGxn4N=kq!0|v?hn$)+xJ4it?Ro31Ft<8Nh(xBV8c1%|V33?T^8_g9@Z94;Li) zc{ggCd1bLC#VT&a>bg+oODfGb?Prgln6Hm6DJj^zmbFa3I!%#{QAU#LXS{K6foRvz zVGJwJ)R~Y6a|PTc+_!zXxts{SQWm%%M>1KdT3nPsPP$MSlmGd-4E$2Wj4>DE0{&JF z_KRA+Xy8NS`Q~LSLNqCXb z5AtZ%kvmy(jdS}8uX~%2yPjN@sV8K;)~o_*AUcE4funapb*87tyZ&4~mBK)sT?=Y) zC6rp|WhX`AxDmwN%Do6B9ciixgnLMw#H%&euf;7Z(GzDc{okq?h;0Pv%xJEJ_?NBUh6>))5_WaO!JE%F!&f&`0*zLGer9y##^p1YT9LnAO8nU( z?$YU>PW);2zq1x`r+=E2>AC#ul>C?DC$j9n#GR7o(f2vU(Ym2NA>^fB^I!2;WoD$Q zsA&eHWI4+F)waA%xdvo0WTe8=W`?J_?`(t89z4VV)@=qG_DgIT{!``9nN$bh--;W4TjGI2TP z>T<{ZwNwo=FtZ3e=fs)RP=91~o%P-iyWzfiv5f0+5-IswB;^$*e^Bo_>ZO3O(h>6$ zXY=xtLc7P*&#&A^d{q6QMM0>n7g;7K&h6NrY~4dt+ds?Kz2w$~ZZZWkYhWhTHt&N! zxUa_2i^xNb%v?-rBsu$R^l9*AkXpd+CkMKoz%ETZR^vQj)mu?P`0$#z_H%x%nGKf7 zmB{|hFr&}?s$ca&?uz>=POQ_gp#uyfBb$8fgOIYzRq$LRKp#v{fq>{Qs~(;T6^Iwm z7u&Uq`bRNti1e(``mBp>_eHen3q4tXV}&KXB(;f)`=2-z3&Ii&yJINs|Hs_KRp3 z$X!^H=V6_U`}kKN*KedPd5KiuDD~3+FXFjF3fIJN{tb;}WsZM^!TwbIoa-Fv;&m@! zXF>U(n%h7%L8Lz<(%J4{Q+y>oy_8P7Hp!itZ2xQPhAM50wg&vah!#SfuGw& zV$iQ!F06ffofmjV`fOB>M;qjIyY!su&vhFwNJW2ko0SkTs{b^d&F^YDt7V*_b_!l8l;lZklFb)7#l<{9uH z`!pcwa~A=mlx{XN5go9=*|ZC zl|X?p&I{fd8OU(IZ~;P|G}P9d*U7?F=DELN1|AcpIRTJvBiQJ~;`iY}U+XXs5NFW0lFg0Zjz_ z0!=8&Kg(u6>_X&Q<_9ht_*~)~4N{>t03Gc-6wx9I)l-FT{A}y-aXu+8z9)y>dM+ey z`-{NeU&qT{jen7Y_NyE*L_CLy`u;4}k(1J;AK-!iXQ{d)dTFftlM2$gJ9_rcS;Q`byxJ@17j+XvZna9myVb80ogqh@Q3S&TS*{{W5fplQvo#p3tv$czy-t z!PkvrJ21rieM}{uOt;T?28JpM<0(To;_GR55t=Dlnkfuztt%LtwkPdpeL0;0%uZ3r z)~_zv_R?l=j)TNhqB~*$^~)6M@RouvaBto; z9ioxqJ*C}d_uAENyKTghFRt+W14aDkfe20NgJJK!{oX4`Syl1`u8$o}z&ySEozhJP zCY^LMBE}CM$GzOJxfB8}K}CZ-%v2qB-EWAN{kAkqcnuHByzpEp)K2-wcPod`%eE{t zR-%Y>wyw+@g(&4Lg!SJ$8&C_J_Pb7=+&nJx;C&n8BfpmIkDS;CFf6%NdMf|^Hxol# z{vZE>BXkScbp0FqW~4;B;66RpUU;v3Y!1FI1&Ckyp@(TpIqhyKo~L6?09iUBA~pz8 zPpa_UioF8uwmXbS$MIxLjT9=lEu(d`w>Xw6m}nawkH~&dHBt9iGKDrDE;vwE=t=IHYn;r4g6Q*(6mxFhH+ zFE1~LJ$G@U^q;qteq&*+CpxY+`*~=}krrBhuPzz-I3;|03f+Ltr)=eInV)69P!Z##sK2zK!{iBoOnnx|Fy>HvZ3_;(H9P~-gG}CJY z*94s&%xT*E#lF)a1?pSemob$y=BD6zcoA#{v{YJczF%tQ@oz)w{>_vG0v<|YTD*!{ zz*gL?n;;KE87w;H!R66ZHJ(EU(2+hv<3D9Td;Tsl{f=PVo-VSL@mnQ$8IL={_*5?q?23UU~{nY-KeOJ4V2OP(W8%zE{DyAv>t+~ z1m;1dM?);X-#HtRvVsXUh^d=;k77?~0wDmPdf3YcO+TswomZ@S(WG0rFS``iVV7|N zf9K^%4`+(F2!<(&9u?ByeZ!ndOq66xZ7DZ^5kU4}*Cg(&uS zsX&utbS?vTVD{=*RCApvXDzp(O#zS8Ld6F4(5|GN_sP!?kyAMWb53${#T!@~A{Z4S z6jc%Fgx0anZ*a|R+49db@6F6!sJgVjA(T)6^WT?7mdMyKbebE@OvnDUFOluztm6ee z`z9UK1*P2_clt{kK6tN3ui z`3&QP2k7jYn$mU=0Z52q#5P85Sg|1ZJ~cX zzns_Y-@THE|A}wyA9Qxhi>cc7U(xNSDal=zrUNDrnjp@JSM2fGlp1v&Jkl=aCCR+N z_DLc8L__KjF=j0<<$G360!#hBo)I}o|5QDkvdOT^kb69-yE}i5FlGDh>4kOSDudoA zVfF2fw{?|pa+Ap7KZ@<$-AVHgM<36t(-fnqfD2@|W7So%5vKyl{h=_&QVNbU_2JT> zY}BiN0n$9oSzvw z^L!*XK==`QztVyiX#>9nh}`8wO)(zLzd`sM` zSHW!+Epm+ieu}%NZTz8Rc^`Y?)b^<;#i?4hrWVZ|9mhO07`iEW+%1cpIRLVM-f}J9 zk}K9gmHHK`BVVg_K7=Z=n<sSP zJGJzLg=;_SA2K!ia!>7&dEC$EugpLF`$$~rU!VTAvUkAN_Jlb+u**tL#L~3)PDRrR zTl=Q_@w9H{RW`3BIZ&qAR9La*AphVX@P5 zur7v8?=z{(mTP_(#SWtCIBso9SohnqTPG%(^SV(t;J1zrZWp;k zZ?=w|vY~nOi9AdKa<^P)I!jK3pLJdQGx%ELlzX(Gq2evRv6ECx$}cCU&uo?igm_xH zOvWfvL}SO zT4&i&TjO0&RC5Bu#f)pCJi6_1vIYYcCnJ+{=^uF0iMEpMbF+)jKWza=np@7}*UfM% zrs2x|ZVM?Delgp@8MMHUf~2(1AHd^u+sm=NF@p`QV+7RTHQSgd;KW3CeNNLnrU0aQ z64ETvKG&}#o4|-zjhu)R(>brQ9ImCEUY`RmD!{ZP$$Jm72fLu!8HCSww`@i#!iFna z)ZQ0h%AVxPMJ(L7(F4O;m-x_lseCWeM=)PofdBs?sk=w-R@5|&Afm^ylib<~b zz`WdFGg@qhT$1*z!leWKB+P+ExZp~e8O=&?dVY1OaDcJ0pjyjfEEfFg&qKD3ZHcNR zyhgkrMw0Q#^_Wsj<{bg`B+)2eo|zT5XESqQ_n8XAWy_JwdoU3fg@E3Hml2=VMBOvV zUm^8+`!FlIXovi5f#s4d(cVdH(X%SJ&%#Mx*88x$5!eX$orL^=d>KNgRukg6<3f%!u_-|q;w$ehZV0PUxC^wyjN9?uJTRSWZq`SjD3AN= z%c|1<@BtHao%=Eb63gm z6nRE6uvXr3ZVt%F$Vrd6wp+0$ehSaa|5#8_O6<>J8&1c{ggs0aGTXgNGze$GttkBd z3uxNt&;?2?a)*>H6l(Lfj2XoJKc2obpsB1|`_5R?|s^Op0%^r z+Use5>WjN2?Gb2s#{EjQzpxXVPxtOFjO`7+o4{L^L4-#s=Dc=X)WQ;t~_6PqWCxd%?DxfW-qN-Y8H2Sxa)% zFQp<oFbdi zPCjH-30d`-Kv4Vg@=o)Kiyx!(&M3P)Dzw1{($uDE?nRzUUONSW-#ihiG^{7%(ht6x z+J4%~_Z!K`B=ih+YLB-wa5JuvlvkQ;C296Jta_r`njzjQUlGGPH1t}%8Xaq>+u8?3 zgbJ%vO+WaP_&oD0t_r_{ynuFU9ahJH=_}HFmy_G2X8)$^NU!+}WetN0S63!RQG2sp zt9|O-Rb0})nCVO>w7_oCAO&yhb?`a$T$=f!ijG}b!1Y=B9hN>0ju{ELN8FQgZhIM9 zq&;~lnUwd)se1dZHMI!Ug#D0B8q3a^3WooCRq($Uk>xu>!P5!Iq$;0Vu07%e#5Xj=~uApN5{< zIIKWWEVh}n7t*M5LlAH+ek$P6o!;~D7k7>N$Dpi`_l6%<`Zg}7u9y20@$1H+_$KgO z=IUe4>qFCClS%qqxiba4b0l8WZ(mgA^N-Yk#XppkNdCrFRUG*`NH?`3qFl2G&`DQ< zB;DrdM`-3i8pxIlzksD|@83F;h3dC8{Cc|qsE;LwDyj#$L--;8jg}u1SJfNYeJQmB zc0F9EK8@-wUC}C_i4zYF8&4%S@4E~rBisLtns+=Q23~PsMW!*64p+4uzTTLRg?_G4 zZauzt{}zD$W3hHgI!m0-%|q;k|FTN`4x(=>l5`^jxQ^B1Cs}$Nr73pKQvcy=XYB@) zM=SMMQ|z8Z5MF%C-Uwa+NyyFT95RDcE0*#6Uxwdm-x@(*iaSSP>B^2WE>FYeqa@D2 zklmOi{UpHtpv5hW_iZ&PrjtR@Z(+9s9h0PD)#)_ypKFOWShA0UigPbS@?VPI)k9$$ zQ7f1b^AIz$NWNIb@S9pcKl1KA|FR3;i2S*48gw9t`~%wbCq+cs8`vNh8kmB?;zw1& zoZ1*Ryk?(kOmTH->c7q+gI)OfzLkc|1i>&gfUJC<@O(%;j^eTJ0zRd{m-o5$4B+Db z!oSWZ45~>dq70dNv`_VllS-p{p^MlRhFU}U%xMUd`NW$luF#O!eDR#nmeJdmgT7MS z=AD(x^C^5j`=o!2DQDsmFK?A6W5uJ<<$-R}scl!SZ^p}}_5#=~aL<2;1kxz9J8c&~ zlT!+}GkbRSZ+!dHw=40OPPJine)ONp^hA|iPqjJA*$SfFUVUlVocl#m-NN~xGi9od zjtcdlPd;N?^SI>%c#kfMtpZP!-8&J!rJdL;^hodAVRtG}b zB}{gQ)c3n{B3R++AXdanWvCJ`SXpaJL)1sVlh{O_?ZGhM+X=QR@*%T>-~^x+ziMcU zM8K4bQ9gFEjS~oIn*g`l5OO$MrLLdGI!-410JD+H=2R`)6`I zhyQKZaQG>+TW-dyu5dbg0FDcmx2CDgS2-eLos`Q=%08(6B+IQi1wtt`Q9|-g6_KkC zjXTIsyxqm&HyFAgu}aRq^?~&iXJzYz(aTl~^unGcFJwTd%Lpe9Y>)-;@A?9gc>{BL zbi*SX@zHc*ag;#4Q#hI37U$BvamcQ=g*28E?mjo-PjqnQT17&wY zB}&#el~zJ4D8{|gw4bx0v}otuU=lE)p>4l5dsV9!=YDM)>eQ}`F5f&o&)G^7_6fPj zY>OE`1dBu4u0zBdNv{G0_Y52QI?uejf+4CAZPcQhR-LDzqDO?}v)lx9*!4-?Oqk<> z3-y1*(`^i8CJSmiZ2um=|JHfYnpGP80S>^H|9Gt^HDk#;tlu8?e}`Ftxvp!6Q82|P zIlC^^K7I@6fn5pcets+=NTWL_?JZuN>Rq)f*5pm=2zQ=6q=w()a%Dfe4WLc|Qv!{D za@aq?o<)xjBVm%4`nkV2uNd6LFVVk!J2Rzpm>BiowVMr~ShMoLWGLa>z`~>H2O%xm z>AFuJK~}F`3znDrdDq1CxJbbH<07X|2PAtYSe^-Zr!i-G`}uj_$NdkxQWBLO|9SK_ z_@t86(P(7vu6(>rW=+jPP`i2oKV`oVMlXl^wX-6ra%Y(@R*z#=uXCXiAhJD&QT=+Th=rVZ~iWDmH{BaG_E4pweaGN#Vg zNTE-;zF|e78Pc|B(e~Hc4GMU&>C&=0)XB0@`TOLx$`70^PiIk9Es#*H8O+pdP@L~T z^IYJe4r4<PQ)Ip3korBGD5s%1I8BChw(wpiRFy`B@)hm_#vh&yFXKy>YKcGHc z^)1NmD!O0KcqqN{g=2-eeeI3cPZ}7p|A38 zVV68;pe#t+H9Xh|BtM@w)An5ikUzG5EDJo1>v;92yoo305CcRsGYKk{K4p%P&w%jR z!^7P6C&V8WCl%f zh=j4Fi5pAk#dc)z6C$XRt+Mj<=b=B6!nKD>IfSBE;xIo zW7N977RHhc3hpP_xqO@FCcus;uC@R;-j2Hk9|_caRrH};Y`*oQyl#F2gr{rdM!Fk0 z8By7~1Z+hdu68l{;8#npc~>3p42=N``nHy8UG%4bk8VNC56vpdtFnY`wCjQQU+vPg zM)5X2Zd3#W?~gYf6>CtBOgih{pcxWaoi#f)OzqOrFkPynqQlpasAbq)&@&}zgaE#D zt%a+iQ`=FI62E-&T~u5_Yj$Ifoqk7W>Kf@(HTefRg)RQJJ883hY<){h-= z(Nvd8I&SHxS6IE#$DF(&C5ce%xzQa>?`xO>mYh2)FH9bGxYsVK9t7L3=I$Ll2m`tR zHz@QhmM+;!KX4QW&iB6Kakk%6D8_FqatPH4^bi#&ZP~l!pnWz%h?{yt$^no<9MAjS z?|)qf3K9J5EkJiy>c$b3bfYiAEegk(g{$MRR0K7DcKztQ_D1)h377kDFhdB_S@R`0 zXmAG{{8tk)VOKCHI;6RL5uP@>#0_W?4Lo>f=4M-Q-4WT@HoxBnckn;8Lgpuyvk!4f z;CAN6x@&H~njLd3Gu;fCbK-_$P(>Fl*%2ubK?;<-h0{*sD#)944+vKthVJvzCD#p2 z(@KxU*KzeWhT_~K9?6WV>KFM1dDmlrcig8xwzTB`S18t2|L|ra+*fzAAE=iMw2+R? zKX*4;vt^nb7#lA0nJQHTtgN&ZL)JR7TraDC%uB3rr7iv-T@@0{6B#$iarj$U_OZzvx(O# zQm~|t|6Iv#tcogHw#nMAmHXAIXB!8ph4nY(^m$d)c(}=&W028D%Cq?w)1%rUi`lp0 z#UagS2VM5k2EUIQxC2B@M&PyBO znov!>rZw3^K{GB^F|}^NVM`xifE8)D(Mpq?rhAq$sU+DeyP&cvDzj#Im4wbe(DXHx zJmjHsV&s4XzmVhP|CnjiPo*v7v_xonz-thh`iuSb<8sL05Ib0Y6+i;3aWgxl<4Qt! zYl@1@DD|P;R-b*C-%#_?_Sf@Lr_vDtKU?DOfUHerXyN^!FVv+Gm;Lc`gFaU})$)SU zA7k}E&m5#w;|nE#yAMfrA3M9Vbg(wt>r*VnvV-}(nW)lm?lI%@$=6o@*rwF;AoPD^ z9@erlCIaXT1lM&9EXEdMr${?x%#nv||#d<8*SMD^3y7>gGbYjrF zZQiu7aUlX)OKxe5TaoWT)hm*e-)@&XPRQ;lmSB<3y&tg~gZxv)M&&A7WH0F>A{3u16eiNiUsm{EaNR&6I#AQ#@-BhIpQ2sp1%7pLX9PQ}*6BVe1?6tnd zPqcE?p=|b)KX^q~$^tclIxKOnbvD9!9nQOQ3U3`P)7KX@l>}s?#e}SsnOrjTa@;Z* z?$2r;S7j8&D<}WzM5j-pPYoYTGci(VfD%2)Xx4v9-YHrk! zl|wc5dm3uXk<4l=^@|SjoslibMhVbz53E`UfAfcetrK!%-;%>x%>utm0pyy(phMqh z$No5KL^_Bw@KNG!`+NTk3m8(~njPzv;zC*u{z61v+odk#;Bh()H)FFHyy@p4HDBGd zDfK0^N~$8NKM~%hs2>n61;4TT10aV6*VwFs-za|V`Z`ikYKN3_*kmdPwCcB8j(R04 zgpY$LsC(?n+RCCZWGT2Sz&H+0xgzW_F%&tsd39rN!7L7<8qm)U)x~JnFuF?^vWlz@ z_8Saxbv#EaLgT73be#PFcsi}~qx$n>A3!lkLHx5hTiw1#6z6PZDKtWLim7qFsO+nP z)*kO^{R6^~M`f_jxrwr()*gT5k$S~@x{#+xDRzY52+i)##RnD6$n7oM>cYjV5lV}2 zOTB{C+&#=MTN*CpftkMQgg$>of4=+sqUC&JR(6B#?OoyxO4GHlpiWh%e0#g7TORp- z2@~s9SjP0FnU#t<7tzP6qvX{nHijTL?ACS0+O>*oy54+dzDkA6(@p@sZqC9AeaWUp*oR2=3WYESlq;%U<^8TjB<17A9EAe53{^cqj8kr2G`W z7Fn1@>0Rz|<7qw+~kj+%&gGXjZ663(#6vvg#|Y8196F12^RXENf$^ zXx6?diXEn8(BN;HXU2h_-u3q<&!4BxwEW7g!Ee4=>oZ7ENS};_kwGu0+D8}}ZmCi0 zdOr{9o?t0`za3oA$zn3%56wBpKgqpU$08V$PC5ol3+o8H?Y}n7Ek$h&>EPsf1r9EP zBXaVyqC0=F)s>8V1;GJQE0gxu;6j__viW$%fn`N;nn+$MR9m_b2j+_@F1Y%%*d*5vnB;T>y3KqJ zds{o$I#U&y`@tJ46>O|i6BU)siCmqhZa@u!_ZKsw-{=&qo?|PC!Zm#GD|y`9Ax)r0 z@|%rY+e?3vT!@*F?2q1{v&s5Gn|#=tBmCvy>!VBde*}>$!%~Nrt}103a<25PxYMtB zQ=}R+v=_$W)7zbUJJG@nTc@RYr{ps9ae3O*NAJP~YsQOhJEa=7>_PWuv$V{S_2e^)!Gm2N%AMrwO? zQ3LTpZU!Op@sOm#3PO4&;O(MoAfaCl_9np8gX?_DQPaYm=ztoX-@ZAC<7JW^F!A9X zJ7AEM_HT%0bLPBvh}n(}m@E5^D;j$kV)<`LfB+Apq({YVNAJySnoJtK$g+6!V@N(V z>HOb+o<0$yddBsie_o0ozohloUw?VI-q<+(TIIg5FrT2YvGMbzuj2Ars+aB-YTiQZ zMf#FtHCh#Y(jyrnwZVJaSmHqyy`5o4*(d37SCd%o1p&Cd|7Z*;$>_3p&Z_i;WRS@A zvsDYU0zNOz2H1{L5LqM$Ro%b4P;x+98*g)NT$10j-5KmTUz6$V8nXJSavI&^FEN>P z4sPCbNrxh>T@p@`))wfvx%u56*7R3IB~Vg3iOk6@S3-0K&14W^ z!M3A2kLGfUS!%xG(zNPrb^#?D_SFfGaBhub>j9~THI`tZRC8?G_V@L-{?0edYCo%j zNv?~V?z6dHZ}&?m2=87(T$NuS{6Uk{<9pv0h`R6mI6aOx+ay8I=k7(V!}?$GwLtnT z@Jjt~=bTnAKaVwD!h}%0rqPrzm;yfC)}Rvcz8iI!dADX}F!8Uzhu5uzCWxz0iR}Sr zC_21?G2vLf7fMU=D)9iPs5vPvjE%lX9c0l};nI@CO5ysl8c4w$F=y?2*xKJ?qB4TD zPim%yH(NOGoO}dV3U^#*#!7$Fxk*_}w;ic}hp7(;iIwy}wH_qe>-m$007f?MaN(!id6!X$#OZ-CJgSvD?&`ux`vu_(01?Ob#{QKH@4`DxEJ?Q?6+ALfPhk ze%%@)3x~L?Ry{?1K3nfas1HuD#MXhj(fP3hTTAEMx3zG^=_>V*rC1~J29!@TFM;$5 z{yVbC98kBPdIYI5n}gkUYW2!hS#r2es_Up^8gmiHu}zNDk8AA#N+dq2d-DE|d)&F) zt)KhOCmLYilsorcYYZuKLLL}W=F6q$i7hv_jSJsQiuI$KRs5C+9NR6AdlNP3oA+2+ z{KPA#0~f9H_#;8d(h7V_%)I#;0ivGiM)?mLLb7m5CE6krUxw=z($RxCPsWBdF`j$H>|zV-1bHcPU^?+p7#6byb0a^ zAgELZ$wdfFE#)2L71Rf@Q;W5Onf63!ZQX$o4g3gN77*GFKL~0j^$zDxAEf;B>qb|8 z>nIrPOlU`JX{p!eV&|-s_9Kr+RcI4wVZba`9r@S8l{(iB{+njamUY5hn#B%6Ews{`Ozo_13-n?(my0!~YDefOB%Ff3g?(;vq#G`Zh-$2j-KWkktq>V_7P!o(+jKED>d_=J^Uu)_66N6TY0DG8+7 zgslkItx?6b{1{68lr&MJ#%R;H;)?rzT{qQWadS2-UqsPM=$zK)cw9qUpkU^3 zP1L=4FYkMJJ3uWZ>(_3t2JDOhwyqU|C#M&3v;zpTEg`p_Sq2t0PsoM_+Kf%DxB9&* zaR0v9oqZ=|m@foSk+&-ZyR?&sXYyc=j7HVCRRwJ@30H7Rwf!$!$ad%Hv)})Y6d6_gkn2{x)A9srujcU z-Y1;6&vRZ8_~_n$aAVp&DWepl)OrL!3Xxn<{CX8ZVs{Vw$|p_JP9I znsFitbXJYeFA`(iDx+2BHQ-0rEFCLT;#n6tJT#;*pOZ(?8LP6?`E2LBBc}oNF$LJ= zyo1D&t*P^4#zNc}Dl*XkkzGl6RU_ai#57f$({pZvX&Y1Yb>Zs4D28Pu3`u03J zoO~c#Om{w19vU7GdTvJS>HA{Mkr@Hb2)trdi8=WCEbkIwZ(RN5Y)Hmv4MR?WBN*-@ z9+jF)|Kc-9d#|Z(Wc&-UsQZa=+3alDKITi2i3EP~z{1?;-4^Vg~3^4@va_^HV_QFWUybA%8ti`=N1c=}SoGJGw}bx!5u+tl+W1K4-{_C`a6EM_VpRjna+#?l@6f&>cA-?16$=*=rbdf$~K;v)+QSPuPj;gCpBE=cr3G0;qfy5i~@+wx@MoB1@%j_aoY5yC?Ri}W~rwJ+Lw!q})$@Zfy^#1LE^dJ26`u37T3mI@ zepz*z>k=8DIL|3t8qI4eInM{$cza{>Z-g^l^7SEc1ku})7mqSVE)FKE+&8^$lcFdE z6%D1?Mj>`j17?qbg!P$)Szh!i3iBMSLK##UW}@=aM!xt=MSqcYbfg3HGU7@?yXEg) z*7~e=P#kdFaqe{XZQ?M?K1vUq1oBj$wji$=^J&M!`C?CYu05)|;B z+6KXcxBk^8ttC25bNlTmwL~&^b$Kz8yX{Ed(Fxla6tJO`Qp|?j<-z|@!q9mTlkc)j zZJ9y6kj@vI*fZms(T)n;A~MA7#8Fgg(3IKm!4um*I?=n@ zOEPX@qxj)!-uT_!)?%s2e+2iX{d9)skoHw*F?M|519ImPC{lf+8JF9|cjTa5Y1crp z*F3U|Q?Q9OkdDtcswVh*?<3BohsS-8MaB=;`1YsFw$9$2-@QAAJHIBWxR0sNguh3t zn7-h2h5Rs>#a2s8N>K>OwI?I+c$%HUle ztgmzY!@V>0NcOsGXnA*F0)%Piu;AoU1(NeMWQ^r6$Kt>3eiiAd{_x(X7Fh7s%5psb zTgE})G+QirJrOd6z7LXZ)z5(FbUuW(j?Dpzwb$5pA(58>O|^E2-$w-Og<;4sat|Eq z&G?A|qKOEa&ZB?`H_ZkOL_lAV8zToUx-tcljyl_m9$|9KZ`Z5~wPDNMM9$^C^{ei6rQ zy*E8MYN&K*Ic1a&i6sB9ID(}zu9oPqZxR{3TH1!!C01j63;YDZl`87`(thHQwTUj- zqp4Kq}Lvc5Rn;uN+9uV)^XN@i8V>@LVKROQx z>nxD36E99~DyGprH=3^!;vl3(2>e=awvHxYpn2&Q5QvnTyy?<{B>F`kJd=SbKLfr< zI-V}dvT<~1sW}Hk$K*t=Ys02zB8)+Q#z8vKCgl1m{CtS9)hX(GC)c)V`IY`WrM~A%?g-Z`W^bV)V>e05f91gd4*^tE{&*$K4 z)+R;}AhU77QV$gE%f;_BuHjF1#^gPoVE?AcR?F3Y5wR=HzG_a;>e;LyzXQC}H?76i0=?eG4@HX1_7>JwxL^M_nn!4roLEI0M)__dhpT~5b5JTPrm}#ncd6B^XiFqZGHDHm-x+T> zJ$M|k5vMN|+R)8>FuiRS+aR-l{aAo#RDe+(u6@YXB;wWx4820N&u=5r4haWgMF3x# zzTWQ4WEx2!21qKbV|ZdLOfg#3g1o-m{K%=$qj~4SjD0GaTn<5%D(`ICeuCYA{(40$ zmFAp19H7sc_B?ZTY>(8dFaRN5om7g;!}qGNY>QJIBozazI95~TkciM~7r}Y60i(d8 zOv?sHFlHF50|S$qjEZ~xy&2Nl867iOEEN!5=7is?z-Jf3X4@tUN{~A)Kdd9Wd9x3x z5Mqy(tgy4k`ovyX(|KyThr?{`U#O_ag`Bnbfrdcb0SLqS#IxXQ`>8S@e80_NIxJ$W z)I@)y@wNkFETvre_**~M;=vb*(C+~^*9*ixamuqO`ofjYvTMUw;mk=O=DUvwqX?-l z08#WnX!>5slc*TA%E1Io;Z)=eSn^Ka3}Z1%8-R0HiO&T}U6Q**QD-Cah``nydErrr zDIiM=fZ1oe@{@CsO9ATu1+#Rv(c)V{J8cC~RaXWhy}VQ9^#NxmK2zj@fgLnZ<3{*v zL?*7GY@v>k)UQIUH{s?o<$d>f6@K@)3!c@P58{D&XFs0}#0%fX&{o7aS8OPXP5b>) zsVNvK)!+WIle~#?>4(^`li={>F{c)$TWWhj^e$58udhVmnrc=* zj^E~lb4J>mqYvG@w*Rw6$NjYEnTY<#*3?d01-$(^0XfC!e)1GsBb%pm*amR*bFDDS zyUumhPLUQ|o~z2EeTKT(1Xle08mczc&d#Y+3 zN%b7DJRJA_eM6B~h%w>p?mnJPA0*AHd9-|5v_ZwWqeAJzfd5gSa*ei)-%WtYAK4WGs_wN ztI_N+S@vHZI5_8f0;mss{&b(s-m1R9=OkD;`*VhoJk$2DeWH4lX=o3`w4Yzc z#(qdeLd?giTI1rfr+1^nHyxM|Jp`Fm;(FM z2GCl-u7lh8@BXWtfGT2neRALU4+13HLb>-tO5OMB%(5;TPDZ6Z`ddO_CY5{?v8PCHlOR`h@X6CQWEq+AB-GbPdjn{ zjBupIeC!KG$g{|S-XfPl(07o#0h98b#K02wk?riMYJy#KX%0N%XUZ*I$WOb!(D{IoeX)1P z@w;OxElt_$ULs7sA=Fv&QVl!Mvt%T{x0~&6SAqWyt0{y8@Ukuq5Kq>>fsNBW)`n=or8gK3G}-;5{u zK0fhQvFr{|7q6ThTGubj*u9q!!1~YG=^Wus*?XKKf!mC zgf8nPO(_cDV$jyA!H>Z{ZxFw}3h_Y%rsrSp+QQD7dS2LeZ2#!Yc{}$D|6Ue~c*hxc zK4TMYE`coE7frsWZ!Mc!s=A$2>9=BKSfbAd>98F>IvU+kIOmnQdEP=f0sSRZ*}FWj zAHM?2bdR_lF<`{5U|NOs<6ZT#SU(eY9s~s4LCTx0Ji(sCJv^rnMov~T8Du>bxLTjm zqF~Vv6E9*bUM_O6NKL0w^Mb818zK$BDzfm$;fmr4uT<#Ktn0027vdDucb@2Ws-KK{ zc8T~1eA(yw!j_20=xL-eJsfP}0GBJ&-msXHAU*^O6NvD%rntTFRtQO3IV8y0kwScc z=tI8QFW1EN4yI<(HfzgFHnz@yf0{DVo64ToZaO7wsT_Hry`X)$przw6j_^^7I=7kR zMa~nZ_U675l784?f#^R&n$dF2UK><}Y2x=0rhD*R>c?mWL7Wyr99sW`-+fIK+%f+7 zF0bxxD@8u#(pq|_%!O1=`*%;HmB8x9=Wy%qb*$lS7*mkPjqkjPf39(x$bRz5Vpxp= z+WEqqs8yF`lkN`Nu;dQmZ{_vE{5Z)@pkNDQP;kT0KgLx*9-9 z2*)V^8&Jk>_s8q_3VhV+U4=gmlt#=L4LGohV)8*N3CsFFpDlZNri^6w<}Zk{gTJHG zsbJ=5JQxMkTWep}6TG7Cu>GWpmt1Y3eM9KW73zEGalGa|_yvvv+cHdgBi<503sBp* z*CDYum7uuv^2GfnGro{b!;I{7yLy%cBFy%n;KxaM5yF+4Uf40nn!B++GfqQ~-Hd%F zkQDLlf+Y9#cSASd+PMltt?Hzl6S#-DshQ*Zg_`V(b1P;m_@(DJm!5^m-k0KyX;;e9 zjtW=n8CoUtY`xJ@RT2O(5WT)WZ*zW)_DiV#kO*n0znm&}I2nxwpd>b|Ts_x&2B*lizm44bfz^cr%0XRG(m#;uM&At5j3ZMyV)T1m7pFkPk^_Bw&lP*OOP$J8U;01GB@A)FVldUY$$2|G%S| z8XvdG=^GD?ItH*5Z0A-6Pgn)V-e}U_<~^x8i)*Wib5Cye_`A1i7czNacXvL}REBVi zB_(1sxdRuA)Y2xTMTr3xAx>Fzi9FH^(JXE=iOD{fz_8|UGgo8fiB_Mz9<_IiGY)r@Re|!Z zuy_w6P+b#?tsfr_1%tvO^gmq?c&MF@d~5UZ#p7qrn5bk;o57>Bz)vwo2Ln&wW%r!2U$4A?{ z`po*vjhVBQ?2i~l>glQa*2pZ>Xov#P1*vc;iKUN^)m;(mCZ%(`!x3`71$?@dm`h=OBUfo3+z;F}nau>Y}| z`5*yvc0U0mNBUMjyWlU~#C4^ziZlsobBXhT(q*yeAr87k9J2Z$%GA|cNA4$X(_G`9 z{>GW#aK9kW(vg|N*dL_}7k6BYyOQ4X2F}eFoSQ5T%|6QZco=iJ=2Z@_D~q+7Tvi@rp1CN2m6a00Ia$U%HQ;OQ=`*hx zC%*pCV*UOg=Bn#k+6V;=jQD5aa-UeU~)#H}WPSw1geI5KtMfHeTviUl&-TdOO z#`Wp%8sA+674hOeNL3vA^pyYgS_2)W4bYMOWqeOD_-TJZt_sd`E~UfvYI27;w$Ahd z?sVkw#d9Z%=$ZZEJn^+;n@gcBAkf+XPk;^=ytLKp>E3oFHT}l_K!+cEp5Kr_%oeax zAFj^lt)mwfY-N-|r07eW`iU^$rHaSOt3Jc{b7ZB0Uo)~i=FcZ+?QCEwMHrdue3!*9 zE(Lj%9EE7EAsjxx>L+g{o~Djp+t__Wi&bn|gj<05R0hNRnFTaQev9HhHxP9>Q z$;qfEvCt3w)KeVeyQ^9SI@GjOO|gT6*hY7e$NVktzK9$&&io!-?KIgbJ{Qo-x{&Iu zxn`(a)f~C3asN_5!+iw9+*p4pyx>`b^+(MR*QAYe9Ve<;IH}@Xy=t29btFKR5BM55bgaU zj>zM_7VNIIYA^%LY!kApiq|PM$?5#O6q6E!s+9aQOlP!N9fX%3g2wxhh zs2al}uvySKElrs{b3X!vSpbwn0c%kIqG!dRnc}eu6GLr3OS^{8%n$I+_!#jzj57>N zau>{c%OxL}8gpy@F-^|lf^hIl9Axvy2cS8LUzUzVj|!5)dl$}=`F5+;s7)j2j&lz6 z@A$7dpap|pV6EAZx`b%PT4V);E(rVF*>nPO@xjs)^-Py!t-bQchDs5|PA75xcPEG4 zn^(2OTXj7jBAWCtM}9Y|cSkVS(%7oe{zb6ef|&lyZxc9fh3Hev`jaZ%C<)#twcafr}AA09OJy7-kHH5ehtM_(JwHI$0;@RRDuKgVkEUCA|?e*3g&1_Awu zVzRF_UR#=4uw5t?NTYg7sZz!cL}kyOSqA>;Ob(*+^*A z?6pm>UiG02%7hvHS3vTSY?dxHWNAv99T7z>fHQK_^VNN{Kr_$h=FkJw1LJnQCG}2| zS`aCz6GY5u%b;vj)HO>4f82LKt0GIjn`FOKoK5r(8>7sX{7RX93uLz{b7tQS)>sGo z4O2g~mW^fY5&u^9;vlY&$N$7COi}y?1YgbWt{Rb5#9~529Y-r$7^ZtgGofk03Ie># zO3^>*=vvZq?^GW`ec?$?PGjiX6~kT#XRG)t1pY1IU9{K{{i~L#QQB85vt1poq+ZrZ zw>d5YTTM*8j1%Yx=+h?2lPAZ9H=jHPRfl6#ZH`lJM`cNMvj16;fwMwjJG#}O-l@%W z&K(L^BH3Lmo)&|_Y8!tme?$i5<;2rZsUgmhGIWKP?(8NFzEm{1=x2RJM0*Mr6U;);uAz(ZUi zh1}2Wa*isaqqo>OwCLh;oaX$!t+FV|_lkN}xW>+{;4ieIs^9d43x?f_;j7V;kmdIW ztz8a;<15-jxhAM1GA$rH}+WXK2XadiQ9XN+hC%zJ^o~{!E|+gtXGdFlVooF zRwtEbej{$+6&+1Sk3AV#(A&ayM3!>N|95Oh7K)`_E|L#P4NC1k{y~mFi<-2L(3=2G zqF&K4G?qRq+rc91|6l*j>bi!@$5~1c_5a^OVYX!n9Xk#2n-E&G8w=cY7psI7hiqo! z9q0-`_NHb-8!FC8auPyDUpGu7w85S;l*6Lz;F1q@VHHiAfAKb$`flH=9v4mXJ**?kA3m>i?`;u^MQp4~d z+Laz;YK6vQ{GQQg8J6IIb1~eTr)$kM^jupLp47h|cDD*ECjdtU81xbD2_0MEu`cx= z4-2(vDk%?@z&yh7ZK)!5$&cV#!E)Bmz#<>E9}id9=xs{>T*?G(q`uml++_dIZP=Ho z+@F(&XDH}%Ph_GM(+ zwqh2w9F~8pdKZIp=7!eo+K-)!1?{T>uQdeelv*?6=r;p*dDDSuXlD+WpmPErn32+aZ!|hMq|Wr$f;Cwp59}0*kBV5 z!qyPH@ApT<{8X~TAS60T?ERoQrp-2JpiF1kc5j~q-1e77L8_L^YCwNI3Y3PwhSKj& zy6v2e--$>1>-5kJ!#M3JfRJPcf zfzQIA8ZxZf=u=Tn728H;WmUhTxee+v!}6RLdCCeXN>{|CD9sE%(@Qwr7x>M_oGAHE zct0y-bVHnH^mjA(>W8ZaVf~!3$8vxOYThQ#ti#Zt2_#n^_o8P26K8)Z^Ly1+U(jEYh!zzAdvNfJltl94tRh zB}#QWv+-dop1e-95A$yETiAN*Zn^olzpVRy9(3wV_do})aR1=ZuwUKH#beIP5G?`Z zZBUR-j*xC;ljf@U0?PCh`+rtmmxo)~M0&8qW^Fn)WKYPK0hocO+Ld|BJ_>{7FdtY# z{@y|bKtg5|Bdfth_KjC1zkqh{I48wlQ|b?B`q&YIYi62U)i3{-jY=lkF7D}QmIj-d z{?u*Qmg&2Uo#_hEdCg4N_4(%uiaLtFFXwb{NBc$mhiM2kyke>S9XJm%C8;5*jE|7)Oao_d4f#89j z|Cet{&C2SLN9V`3^$_j*1@%OBpQkemH5gN7!E2rg!|5By;yId!Z0BSObrvK;_OAbL zM>*JK=e1K@2c1p3=;QDjDhGV-L)C@pj26RKceM7mAI@|CGTaRIA+e4;&EO}e1f>?z z%9n$pW$~^VRv#xVNKUehRbA}AY!immjG$;n;IC}U*yRb-Hx`dHJqlRfs_u8c_f5cP zJ2@1)GTo$mdm2JxsIVRCvGLYL`dviTIY>v|@%?8WLyyT({4yWSURKz&fZPmL%uS-stAHj71!`FWP8gP|FF6o$DD$HZ#C_Bd4dR~ZB z9(Ay@{eArkDmFL#VbXA_y17>*pqInvte5UlTur!!ehGqNCG4uvbKcB9*VjJqvFCotZUhb;abc->L;xt%fG1HQ z`{svN>8}#^mO?Iot`?(E7{6jvpFV|qAmw#su>mX^e+!iK!SkT7H#N|t4ZwQ}h(G_M zuE?+nWWASUsZDRnHDYchKQmNG2}XG};k*5#2gIlIuSMKQ^x64E`7^1HYil7`XIP2w zCzyEe3U84ze?^SAy9iS3%%Sl`XI9i@g2%&Q;bN7({EMJ}Cu+2e|FY+~OFH6akm2~X z8f(Vg?RELe$5O?#=U* zHG+ecHd(wdk_Ym)v!XZ7`%DVl0ZS6a*`xZl!{s~W9O1nnRrWR#Rxg&cViPbQzw+y!84vT1zTB+@D!<@AXy-vH-aGXJR`)0=d z(T{1fwSQWg)5oo z@G_FX47X~$8}q*KhIFA?R(L-iT_c3|i;-6o;yw#%m)w}o9e7(o3~OuXR+UK0YYzT4 zq#d+U7pNxS);Tg`?XXu{a<#E{CaD2WSt`t}y|W@FQ){2PF+zI{AUBQvFaGHz%X5h( z919IW!>Q@0S@Ou}7l6eXVUrN_k8g|R)!Q##R(LE^|Ce1$=P*>kZRPy`{@&%UEynC6 zI)47YKq%`6?M<)%$@Tw!Ur@cB^lVixG6-FX)skco@qT=k@%B~t*DU+vEG6FwC#`D4 z!W8NXHwl#-^S(Xkl5Z(RxncDxt}DAg=f^N*=j!bBy&J6i8PZhPT9bMRdrY zj8q-KqmvG5`2F*-RL<#hQu{`tNjvu|ljOga^HXm`q3@?1s3a7i^!p4fQbKcPgxrhj zo>Rxx4le))jO!{C9AdqaN*BDGKuM?V)bvdoPbtwZe}Umt|F`y(*=7 zyeBoz_}>Q&6zUAi)UaMfF5J^G2{A4{uhs%c#Ihfro9oGS%x$qA-#>h*fK=a({Lgp) z>66Dxm>%Ns#~RRH)qPfhE;0r*Ts1eIS*Kg^5Ki@SgS zrQY<%+VEMKrKm5Gf7xaLQ(eMsmcx+su<|iFn18elSuyw$Ti5{Gil3Qb z`r?ALYQ^WG`=d=rj(rzM-2xoNoA$1#=kWN8>wSyj< zSF`f?*XS?_#48i{s-9o^2>e#-;0eB!@|aDhN60CnK8aZ3`l+Hlea34P z{aGA>GNjwqNqW(qj@4C0m1tVccnRyb2sBCZe8-1VYe{wh*K4M0Ea%Jyj_1M6G6pF{4ywpmJ3r`r zA`=Lzk&ofUk%-oiX=Wh?P>3vJ>D96Se2bRs&wVInim=!Tmblws`91Z~XtFdu^UjDw)9;!V_x%5FS3QVw3_`jY45O^i1( zUHaIShxywxascD-8B_uD0+*SgeYwkRk5ehmE34A#x^hlEb2v-~-B?>w+%WBo?eakKb?(5!2)apy0~HfKAOH^_II zqaCRk_vt>#8z_MD%+kUR zx&f-aB45x4S0nD-b}n734;44f2}QNloT4)?Bb{t8j0_Yb#G4?qfmbq^kI>kP$8%aK z{4j+un+EVAB4B#`>`Ko$l&+Otqa^wFwH2XC-LEEDk@B_=aLykw51e}^2Tf__QbP{0 zs$8SeNiu=>p+grRu{p=KzJu|H09Fr&a&*A?6ekxBi!#V$Yx8k@p|=e;jwH&xHcGyf zND|%GXM~{|*VeylMwKp_lft=XRrUblh29myR>}hDOq2L&xRB;?XI9%_ zTg`bz?m{*B9RytCp~YXrL?^ zOky-8eLLRJl6?d2hCcJF*P|{cU@wO#dz6n&(8QADler{)TVHSSaN{NGdsg*Draod7 z>i4C1`EbQ9xavL!N_Q$-VMTD3tQ%nP7OfKxQ7rHlnd)cE%K3+xSUsQ=QpMk(x0Iw# zrMB{W_yhXok%YMJ_i7D#zLB#{;PTN+G0Ks07tIh|zHhI?5V4xs#fol?H5>7d8fUD3 z+)ILlFQc~gaL-bMMZ`o|q|OOPH)Hm4`9k}r-6M(cePSnP{Ivk1ZhL;1xPj~AQX7yi zh&?U-VgFhL>w&ZDIZUb9{%B|5N#96WT=(y)ZZ>U#Qr;PFuhb8#>GF)Jdhp@D0|aSV zWR?yfrM@SXWrdPVNa1riGgTdNKvWp-M;Z<16G&Uq$*(<>}xnLdGK5$7~0ff zy`OAHjgOX`L2^{VEKMVm=u&Q>l)Ol+dq3{SXO>^y()+Qc?=Im=&&IQ*VXeN=7jPw^ zaYN%nG8}UBBL?7qj3rXDc0sp9sJEv3bG%>vRgR@@Xrm-TJzC_yx)4jngFo!cJrV!k zr4~j>dOrdjA#ThgWYg3PC%A783T@#%X0gXWB&9F&OQ#NQv`y*+5|^yK%@ItrFEA+R zkF1DlMn$deO2(o8EZV3G(#+KdCr?JNG`qvIM@=V~5zW)Kp*e&WNNl3SXA~4 znB({J4xm*BT&&fur+%3{JTN6LY*hix@L?gI zd~Q#v<~rt)ZXx zU{!25-*Ps6pQ}Hq-?;$j*_NX0_LrD4m(94AqWS!IyuxOL^dO&WfI$VhOt1Wtz?1cxUX=q`KMON-9Ph1lxn`5T`HdRyPpra|0tD+kO_r`+(P&(gGR8dd$oq+VIuO`ORf^GdY30Q032c3S22F=#Nm4|oP{(P3h9oYyzH)PdgVJ;WWB30$g zjGutzLu1VgQwA#=8SR1xod0|UKy}`>{89dYiv%!EOFcyNjLa25mdYOsT7(9dTGuxlSZBa0OGv6J-I+)n0f zeJ#?m5lF6~GXYx9ipq^QUIA&Kx=Lep`PLI;6GHynr;b@_Tv%Dl<0hHAP9+27z0Hvq z#So^@T5o#W<)Q=;oZYP1NjFDTsw;B7Vz-m?ya2%UiI?>Vmc1VGr!+N2nrD`4-(F}j zSbNhUAyNaWX@AvZ+QF$T&~clClA+mbmy8rb254#}7?=TUScSIY{l3S;r35Ibd4%Zu z>*d%T4B_iD{o4k@Wqs_}L9yCZqtRks9K{~t#dDK}AXN@CmhB$LQTK862M3QGSFUC}{qL<#3DLG$doWl*IznkwdH#l}2b4S0O^c=0{EQ=<`E3)toINxz!9T@QE;L ztjO;hURbZ5l-2%(CKavD2RA9f9b098wDh+2;=q<#i2OW_tv35MGrH-Z<|r z&oHw9=10XxbV`^yr?~zp9~bGtUz0w=?kN?ZjCF5Ri+$XP*f^zm_5-}Ty2UU_g=((RQaO$ zB@!hCX(WzJHLZ*P*zMR-4`UVBR)jf=Rn1#`g?$wOYI8wabHvyJQ6-UzyKxH;J}Kh| z;-ZI-MLfqWMt%r_lL8wmRU$(=iF7N&OK#(w@1-`-mh}pN&4gm|#tFXpLz#5M@_C50 z?eOBzl#iswC1nmR38g@wf@j99yV zg1)Xw_Am3zufLU#2zn?CD;J&QgH?!pPzbvAY1?P)`Q3^)sq3z`tg6_XR`UgOVftd4 zZW6xdOh(kjN0~kkfI7~P>}RG^Q*$S~uJ2u2e>)Rv)iWYRRfA-;bE{A;IZ+s`9o7Q{ z<)StM2ln{K+kr&~WbLrBd8Ls)a>yiNs#p;;x767=-UFd=$J2!LzesA@(bBReQ2rCp%51baMII9uC#!@T)fz!Zgt!*T{3I-OKXajlaeY z?+Y>~rrk`BYc2&L|2>E?I?|}AeG4GU9RiOy!ucGkh>=wzKVheM?798NV0ZC3bcL;I zYR$l6b12@tcH0n88o~(2*-r23MuQw(Vn=N0C!n>RdV{BC!#d~dXPGU{m9v>6!(Yv; z2Hge5MY^ny`06W;vJuN?AOu^{51~=_DX^z5>}W|h;cy^B{cKbGYDO6U%)^afU9f12 zR%C)KYfhULRPJr#18r4RH<{YgbK`8pa?`Q(Zp?1}##PiqOE^@E(Awqro0tePMgh!+ z)1;}+Gyp<9Z=sanqpu$=_5p$_(Nx*kuh6Uas#nLG(z1h_T(X#IyLFn1Exzkj~BiIw`p7n2P+%#4(|deiW!Ui*x^!n~P&?lzP5tg0Z(q?xJb zo9HR(2TzmTYfH~QR1~|tYp~oiUSEHR-CYyAKt_y5Fm_ke;1ze9A#6GO!zE7rrmY>f zdzkJ#z3=K(3MqS}Yly6vmWyd_Pip}aT9BopDQaBsO3&*9QQXd_+c3yS&*|a(>k!}t zr))9A3Th~Re=(lsMaJs?+D+uqTUjsZ_m@d0;)4#^scdEO`S&tCc3kM~-cGC_NO`ks zr;1O&r#B~PKa3Caz3zFhRtD1|Fw$irSU*QN^v2;-C-p{r6ZTOtL8>B7ksOuDC++z{ z$Y8tMX1Qy`vY;u#pe(FREAtR-Q3Ev$bWUdPPkuv8G0gbzd>A>NqwQ~Yic#W-_3r(i z3dL>q5MM#|`|q!X7=@KJiS~u_HFn*HMn^_C%?n02N8;e8vUze}>H&9oX@UWv9S|rS zk6y+nBj6HqHz5K~abqCey0%n7{rLt&8YACQC=5tm>^}{vyA4s3u`2H&r-XM^C`QRc zI64;v@N`x$p{6t_21&sXPN&^cB$j;76={O@lhkm%Rn1~f^r)#hMu90#ya=rL_j+`m zrsUF0rmat;6xgHo4%|5`O$veyk=;u#-))#lg()9}G(b9A78bs>A@>C&(J|Q{vz|AlbOAq~l-PIbPVYE!t_#1JEb@NmDb5^c=dgc+=pU)<$Ge$( zeJe==MhS`#u=j;u4dzs?k@G4mj-`dGYsip1m#X7Z!#WRY1AA) z7eWTD+aN~gZ5rogpH&p4v&M5A*NIFruo^h7OykBhShv6*pV6CVPQB{@K60+{Pz-`A zkzk>P>@?pt=gs4heQ7^JDl14kn=^ugUIX^@!$2O2DnjEooSKg`-V7Z~ALnswPzl>( zT7wD=ISQf4L1yQhQGbIzNZ{y@u|kxr@6vGBNYd)8B^G3xOg?ZJFz#L4A{BC+s=kQp zDVK`r;Ql>R1k?`VF_ zZd6Ne(!OU!JBMu2Cib)qvzBx@MmAx2`Gp}jiz+gI^QE-eoTY&hGcwPZIzDc+5HgsK zmZM?HQXCohM0aAn-HSgSj8h-tuXO zQ&~^HA_=;*Xc^6Dx{oXy#N%TZVHWVLPAfV2Mb^&qvYQaP3G}85{MU;6TdzQTbgcui z&F?@(TSYMeO=ea(`fWrGr^gXJ8tw2G)IK&r%pjoy7YEc#Cm?WRWo8T zIjHBJ&^R3T{igS*{1!aYY=fm6Qbp7dg#+(ELKLkgY>N)3*H$}B${t4U(n?yBebq5N z|0zcYxV;TTn?o&pd~hiP-nZ@PgS1g8_BJ?&D2Gw3U8xyh$R}H!{peN%1{3}os%(Mprug*8YX!FGO(`hfo3O4N{I@83E; z5LeRM^NIM1P(jg{WtVGgEFo)=wOQ1{7db@@nfpLu*+NZX2^&5q<-z|#+{Qk_sYLLYU~;z z)wzgQ4mAid7?H}9`WYj&czQ-Yg9c`8Eq5IJpQ5uqp&8McCD=<9<0whSVhJZ?SL8oO zN(W~Dxm~fi?!M`Kj}zOJUHKj`Uqy@56YgJh=g159DNiG?i4O?TBINMUFylCSIBTu3 z=dpS4eM@>B)Xmj*9H2}h*pW95u4U~)*$E2U{y#w*2Asv$#J>lK@ay~q`4f+CpZsyw zxF_J$*~BsKlt0jk1db)SyMcM)t)1yOfwaa|GM$Fp$qj_bqC{)I+zyJ}uc z%o*O6BGm4lAz56-?b+C3@8X|TK^xlG8nUC?s2)s*hHzBbm8 z;=yts%RHxAxV-3Wf~on`l!^5m!zU(d{e>b@w0AIKP*k(%uv`;!4<8|bJxngt5^m`iWgumZauQy^eVamovRKiG z2~J8@qOyVK=Hp$o$^32kcR7K0%MP^v#uzOhTov)Qw;a6`{?5=!6m<#c=-Q){nq+cz-p%BH$4lfh?(%RjZL4>9FX1ukuK zX<0dhK1r#o-O4ujs3%@g%f-z@D|Sp`6*ZOHGnbHTP*nB*Vp^YQJYk~V>ir;+Uc?ET}zQ&jP2(&c^@ zJb|u|;!*|hbhBL_7A1|+Q{4{5lWwB&>bIQ=Yynf;{2mg`9M6l3ZWFv#w^$u{~M>v1!9|2%20el2G$Af!waa|ct%ZX@VZGjGmIME`BqL>FSuKOj)NNj->TRyJlA9D;`PC=57Tlvn`cY| zwS;UQ=AeEo96j*eMa+%e#we$3JEi;BD$RwQDCA@U4F8yFf$Yog1<)L_HQ#~)fjAd< ziUyDQQ2{h;?(gN@jM}#bztj2*dY-rxP2M80pYOnaeIaty9CiaOyvLc0|WN zl1KLrCjL=&xn(!M^JvCY)K1Rmq@4Q77}RIcwyfbgTTL~x&%w`24OCiHx_gcA@}2aA zQbkUgNb<0Ul~+ylmUhzleWgXM^~%IX2zOR7^Luxam<)43-lG^&|5duoc}BdwgzCE2 z*cPc1yfnEwa)<8sI3waZ@<5x|B)hMCOgAdLF(6?Qs)bY+54*9iew-4!;P*H-;tJle zS1ISTo!JV9o@D&!t8VtDZBsfouwv)nAqSd-c`sL3y&%6%@BTG*^c?6O^nXR|TJ5Lz z_>sY4bY$~fSXYB3AiV^>>>S_5F1O#rtEr@E`!_Fb9AnzfB^$Q`sAfCfQ`FlmbR{ZD zrfgKnCYOOL00rPfK|%KKuE6&n*k!C{M^HHuRrbvRZ>2IxTHHINamMuY$eQNbRPZ!U z91M@Ur+&0U30rf(cC8vUK%{{JOd3?RJ-o~sd8 z&#(}WR>Kx+`MdG0+qmr6mS3!^2~KyuB@o|v{eXks%@C?I4uLbbdz?nM-i7i=LsO^< ztBxilv-piIy8VdK!8e?mQ{ry#j3NFi2SxS1>4 zieBymQ>#}Bms&ejHT5u+8(G_+Y1cC17qU+-L_$94S6Zi3dalv)10hxl#!PY5KLVe$ z$c^aVveLAPd=p4A-{XvOQM^csU*GzxJ;&j`llaXkg~>XZMeE7IdACoQ2_R_Tu%!m+ zl5A4+w_xvlV+wgBVL||b+SY-+pW8-1Z8TNW)Zla#EM(s=yr=9j{QXAmONbycDZD}R zWt@)E)XSb+$gY}or22eahIp&&)`mO8XTax=OnqN{_I#8d8-q=%5zf~Pa?WYe*B8R8 zW0}v(lfWBezb0^kAx0qziAv$qac8Ie)q0wc~Qn0F58w=bA0U!tegw-QAC`Sz>q>OZq9@BP1dw)O}eNP&tQwK3s$!`^{cB%gV|;a(1FrYbu*TVLtnAoC~5#br9EgPQ{c&UB*%RvwC(%CeI z=WwLOc0?%)((i1O5Yf9OG)Q{lZE-9hOuxG`KUnO*EGR~kgzt8#+cY+TYjNAlC~f&4 zzJptW#5GrNeqyNkuE6Eit=OxQGJDqbKN}+m*n2bkSYqFOa1`eWj&Zd7J?WXWy@+o0 zv{i6VSvN;+?%LkvSdwYt!vz?&(0YqeQDH2^ac}p~uKuBK%Tl&@0)W=6!8R5zcl!4+ z)-`e0Lk>#rHq(YDN4ovH8dh7iV-wB?;v|_Hv9iOBN52zl98Q#(%MDpHm%?w!BYbxy zW->KwhMI=FFOMrcV!Y&q{O>M==*dAV8y2fxKrd_WWD*=W&M(!r@+-aGoaQL*!iGMn zh5rp9=4^DV%SAb=N!Rk!MV3XVcHMR{Zx)%>27K^JElp``l0RYQEVW{k21Q`$iUcXe&LqGJ^rmr#cs?i!T#%0w1tmQq?GL)Uf-qqn{k0G)orOs;&QEC6ZO*e$t?xT5}9fl zL~b_*Qn_3;Z!n1tZRYPuYB|-D*XQ#F*rvGha;fDB($@g=(&Sdk{Mbe=M5*Wv1YU_0 zHL{zyjL4YlIkc4iQRT!#?4vi8iP)uJcKd5`cPqLnsAe`$cGb8Rf|G?Lw-_A#;Sym1 z!b!??(@v~b%Sa3O8;Ywe;epApM66;>2~P3Dv`!}TiqEtUMb*R!2f!~ymgbP zrrp7-uaz?$qHB+^9Uz*cy&q62hZEuY!RaDy>K_0XN%C<&eg@MGYX3O6O&qqcEwC>V z-Iw))d^aZ6c)?Q}jyq>is7Q&YfDXA1(gM^hP+Lt1&AH9{R`WGXj%|NC=L|inv}b?x zzMmn#)~(e)|;#+4=BhkK(jjPSeVSy)6|8QYN=g;=?`g)PWU2232 z0_lxkJrvE4EJpXx>zW0t3VOMO*u)YFyQ(q<@@x3{uf)0X{)TP&th}O<&_GXtS7ADv z_toUr@+Xu)?JemQr9o}gj*J1fF|IxH<1vimFu1psLKP`t#I?A{<4#ek$uFC%yhwXd ziuv;2!D*NL3|8qo@Ks#tK>UIDss7_HT#rhhAD>+!pLnzO=hY`dwnf>CF=DBLtq6F zTYr18+{(6zE5vw%aimT=WMrFd9g&VE!Wdd=Dje@2=w}Wfg9A7j!tcNpfwBEH>kfC8 z`>d;mm@t&UeCD7#@KD-}=K!1-4&`>~ObK1@2*M$&#)LEp-PK1yIQ|@l24rv`a007D z653nswAn9Fz$nr^=bn>7#q6}KX0l5(Ah8Xq3y8P`fBN<~o`X3%v^ z$PS1j7@zyzPN)rewp4l=+-P_3a_Oc~N(WM6d-`-_o-0VyE^vgT)Z33@uUV#I8 z<4&X8*iZVBS(y*~?x{1JleDoyTQ3BJtyvA{`x_-@oJFO_W^PdRjq^k6Ue; z*C7<5${NsH=s7E>C|QudoI34$=iqTkrPHPu=Q#~SYOcFU zKv;GCqWcn;gx0f|@14$w8p<#L?I?<#DQ4U*wP7H1tn|naR^NZGfCpC5=O2V+%vn_i zg~p+yI)ZbRFinUnU??EyMxbw^O#A!q?*Mm_cbw>p_j5$_1{JpBcP?e0mLD;tk~y>` z$h2xAz*qBb7P>1uW{ct5=Oe0F=%HJh3CZ#^@>grk2*W!sxzpb&BlvJ56{@ji4Puv8 zllU~{V7(zBPmW$*ikdYFkH>h{IQO_+&qyPA8NH*WLUu_+2SmxU zzO7F?cgmM*bwkER0@V1;?j~=FyKj$Aj8>xM_r*6w39-$2uD&oE(^;1!ZuWS)U29%_v zoUbFDKLF7Dg;kOr=wSVhIOWIQ@m5-G1M-w5&R(olp@%$|+$@(yKW#thh~GE!SCl6P zYF8;`YxEShM^C7J$N5uCXZP|#9NeIbLJ9iq&Z#CtvA?0)GwpBA@9zvC7U;xGqhuWcRO2{(l)Z_)LWGV z3cwk|L@mkg@UqO`zt;f;afesJ0t0O5+Ndop718?%&B0R9lLEDI{kOIV)^1Qmb(h^&3Hr=Yp9}!lIM}yt zBcnts$jA+9Bglk4MQ87bPWVi=uq>8(o-E~sC?yMTxMEzVw;>{Qge*5?d-Xzc`)`nK z#cxFYaS3eOgh&_HHhHK;bPvAC)_#)J44O9EdnrQn3w%12w)1`d{`{XEE$TyJ+*?kK z`#U^ynS1^NrlqVr%BqYsm_^)WTX$^kxBmycf>m&Dl>q3#yX<=*tZmD45F5J~S=aLGfc6Ng& zG<;F=ZVdZlnRBV1H6RK+HsSb2U`*6Tx{G!#c>Q)#4lE5+j$rwHB_8~c*MRi2rjD4m zToCXAG-zEEW1G+w9fOp>0TBuPIWFuI`> zT+x;aC>o7Un(0TQ1 z1*s?cDZbVHnmW{_{ez|*d`!p7I76$gqe4AoS=Us1y!rW0j+@C_8$>*Fr7r_^oy3~! zCyZ25;mZ(SGD7+9*+?Lm0C@(Y4ufe#mEW!?{jF<^p61M;JMS{7^`) z%t9}=Ty%@7$k8Kh4Ial2i)%KCET#2beU4RcaunlhC|CyUASqM0rNysMaEpa!HBCGV z|I*B1E#(+qv2)RcnEi*}ifEJV30vA9`nQ17=}QO8b>S*xr|jnaTgS2{Wu}yc=bmDi z^tUuEsiL#cgpq(hjJCI_5~)O6w!3`}>R3Fxh74)zF9jP_5Zb9JWiiXgdMN2$$y#k2 zS$66O&B9{b|H}N#cRG@h-FJSJ9@!Pa(TxEmt3tE51)R zM^o~a-Y@Z09le0x`w*m?qOVqI^#la6{6V@kAhqr|3hh1P9cBMbKp_0(bNevFl5C~V zmk*fc_u-c@+Y;*Y_DR7x#D75V+f)aGop?62Fq<$aFsFIs12<-`d03E+bOc zS3Jf<7&`@>J}RXl<0aj-vrU1A<|a$;hQZKp70B=QT4BvI+rn1`3JE@PJGhGdZW3%M zvO}PU<;KQG#L}J~Sr~Jw9f~V`a|1d3P8~4TPe*#iddJOPytpSLc{ff15CN`I`!RW| zRU`(4vv%oBR{kiG@Mc@p3za1A>4^K-NcS1;i$~44^a$idWZavVonmOBQM$pwxMY{I z_K&IW!E+aa+!&1#$;bzOCwR(G+h7P$ITdq2UYa^>wTspp`Qcaw=}1tqR46dEz8S7A zZD~)Pa`&HYnx9GksLYiNX77rn=J>XVPm03t?7D?8V9-UTV77fNXOrAz8I*dE!bPH{ z1lgT*d!64zol9pLd4GG<-C$NZuuq;O2$@s3Yq8R5?VC)WcvaAhJ`CfUcNR+>A1pnH zsvDq;LHn{QSdeU72q09gwMAPd3q9vl+H%B zws?_wTO8|fLdx@FlmE4+0>VTYlCG+r^Zwy!osE=mJn-Tb$c`kqmzFp|)+peg`e39}Q?u3@SQW9$zPhlfo_or1;Bg zUS2yq(=~Ccm9iB-!D;?M+-V3``lh;L1lYq1hLBfx%M!LKvEzL1ECwe*s?{rb(%&>S z+$?5#J)W#91#;SYBgH>1(1_9t>HjeV5*Qb<+to@&9X{YoxKo~X#TT<867xZtk=*p> zjs$#(mf;}4Vc3(q-*=Gf%76!XQjFEH&fvf8xx0ls&lE*wg^NFWq!{ zaU_k_6mZT|Djuji&d(%2o%XpdYJiu@CB99MNVBx_?NvSmJj4&6&%`Lj=ozdtqJK`S zM;ha$Hb<|KyC0p_8+7}1Qbbrvqi{|unJIYnUb@)lS^?jsOYJ#-Y9u3-?+9kq>xItD z#=Zsr#knqekkAztGCp;?PMAD^4k&$uU1Go$c*Wl7ELuAnlXq(#Fg1T^pJXZ2v08UliV65tc^AeB{OI$|-ET;e{)eFCNzl~c zSu+QatosGs0uxbAz?H@NS`*_UtTK&%o!fI*uABEICSojZ$Md2$&7tR_ry= zj0ij(?w+D}%9M1TNdRm33tC=@iWz?fxl-u`)Hd#qiiRd7xvI`^V6}$1z z=;x|S@3cP~ym_WMWAMHB!ZOW_#0$~Xc$P(3c<+x2cvHc0{wXy67Ob~d6^9b?k_J@3 zR)G5CfS*I$>Zq*Isshmx4*QKE$cy)oPUXdKx`~VYeQ*J}Xuq7gHD#^FIeLJf_Jzm5 z2rc#~ZRyGW+oDYu0$hbgu#BSqAm2mLS@{!tf#+HEQnbkc=&tBs-ZfmOU&#<7m92Rn z`=FNRb@n@hP?~ilHxvS|4ld2g7&|yy8-T|P{FrF9omT!VGlfEd|InbdtST!!`Lg__ z%#?RI@?FKdS<`0cEZcvKr?*HnPp_X>*ABr z;J|7}e5NP=YvcEaLrB=_*As}Wn~}<;Kg;?1&PFw-^{?c7mUQ!RG}vhs-Oq+ z7jvXER!Cg_U5t;ujxqBc3;@GWV=D88_UA?e?s9nO4Dc-NR-RWT8PV?zfRUe~spGlE zoRK_;E((U8S@lPt0Nuz!cHFO>m3OI-CVpNK>Xq-g?ZiuEu^1flehR{W%y}sK4bZA7 znI%?Ee)eUx;fjA^zY3p&n{EZP!c&aV@>B}(HDIaC`20Fyh|`|xQsoxYwl1UW_H{I2 z&pg?ov5AnpauyF$4@e66=+5b!+KNKsF}v>@u8Y~ZwHoBOWzlH$FyrJIEiY+ImGS1b z+l4M_Lco%F&WlRIkTp?~eamz&(7jXe8J zY$1-y0PeZpJ4mE7NikkW|1Wody7=!vJyZlK{Nk}-nEqH;@>knFjXr7h(S##Q1)`cU zR^{=ORqRbs%{id;M2R~Jw(9K1Up^%@DmO9KJ-A}X$=0=~luP3MHKJV?_%|uX_*l%`eEjba*M?H;Bm)QIE zu=)DZMOg1@D!%o%YRcY>6l)+eZZV>1SBy#a%G{q>96|I#&?(Z}ENgz2mLNH4U+xQa z?@{o(Fq!?v?(&Px)J5RAaiMp)qNBWk_=kh>v)N|>_0g@`*9%5`_)z*H@XbDL0U%e6 ztM-rkSe<#fjfzi17<8A0=ArEU(`+3d?1S9fkNVL>m9DrI;x*HvnCES?s%<=z@bkR( z6;7O}CKlnQEg(@J**8OPh^UY53)>>a(rom{Yi7{MU&DL8z1sR9W4!BgvB8p&6O7aj z#}VKLG7rmY;Aj#5zgjdx*kwG{`fJGtBIXhm{Cs&h@1Na&G-zK}{*v#HaCWR&VlP%R zf}|JFE|BV2_J})`<@YP){R%heG4Nl-6j9Yq=qcWRv9XKcn#c*^D!o(Zt>KC!|5-F{ zISu$iuo16oQ8y79@0USS*pDMSX7+0DOdSo+a*eMwl`82qhREve1(a1svYz{JDhd@F zth$PK6BP{XMFY=GjW}+o{s1m;WsTWPD?OO31imb#{f!oFzNr1Oj2SY$PJTnn-z$5) zH6Q&?6U`ODtSzg;y7rVXt#LZ3(+PxWo zdvGtB1jt*knHBgb(4!Ib{nz?I#;cb&2B=5)Y>j7Gah5k*g!O)$1|rUIb&>r%IPad3 zaftgu+{{pyAyL{{QQ=!^#Dz3w8q#J}%T?NG;Y!3%I* zRiYLD2G{fwTt645Ut|n`?{SpLzbpvc)+n+>rjgut=k{xw+bhrdc*2zmA{~=ERB;2l zr+#0^C$3mE9SmL}-X8rE?cf&`EHZ$OlHX>3o3%U6CcWS8iQI8FBNXAm6j(esA<(jf za%bhW!}}H`v&~BsV*2PJdEs2L;Di`cWc=xEStzl90dv+g~J!0*->Kl9i#eH4nc#E!j)y*?-u2 z8P#{}BcurY#qp!cY%`cnjYukz$Y{nZkJd@sW1XsNIBs7kY>grh=FG%fWD?y*gH#P1 zpa~J~)pE#Wcf!cV<#vkcl7&prZA7CxVVrnkbVLJBeGl8>C9qy3ndhHWT!wCfdxAxK zp6qcH9gpB*{r=EW;~*K>f*~*Y4}9yt=TA7t2FZy*?01N>WP_lHv-_9DL|B*PM(+bd z5Gf~K2m}`06RG@O@2$qpBLs>=?88`6=vR7LYv%u!ly)7u;}Z1Ga?IBCJHzE@htQ<^ z3b6eCu>k7Q&-(&nw0ddPTOT=PJPJ98{sb(N&ufJIT50nxii<)P0#-lBF<~8#)dCAx zTfBbc{z{nLGiedp0eFFp`AdLXWZ7c8p~vOzGHayN413vJ=ap)*@)b=Zt8W$BR^Z}$E|-}O8_eM@#Gl6frfuHNA%j^ zuHv=@?VO=4y(O}x7KQnDF*qUTO@C4U-T6gYr77!yiXDpWXAn1Fc}x2 z>;1Ct2Qb>m+i0$CcXs=6socs)w-lq`kNiCp?kmyW^x_HY15tcKbwFYJ$tB(Xs&$c_ zbE4mBgH~3lWNSn`ZuJ^G{tCn994X$5SyCg^gUa9Iqtr=iv!_6k79XpIUqP&HO>yaFa} zXpd4g)#3=7pY!dgo8DJe6vFl|hVi>S3A(FO{8`0Fo8}h4w`Er(@Dfr9eX13*v}e;2 zm*N+}wL_T0Hp6c zVpGN=lPAA}&YXS&l6q-)LOSQO|9c~|-|osP8VP=g{gK`twtO^HIwvdZZJ2u#vo&nK zhG7(4u)3eyX5czDw{t#6vn!OV!tCwW-0KbX>{sy&Nk#?Wg^iCl%a@*g@wq_sI-aOMCt2Jot2g)ZfN_av)4A8EW z)1gWwmChz3`8cK3VP0pFd0MHoUtJbrzD``~-U)&x>c0qpxM8#wRbn(w*8X!GE#|v& zZ|;dx+O3dd{VsZ)0?XEL=L~=(JtYQX0aIk;NS!rYGPzHFI<-zJQth4P@ie{jVI3dq z{eeUx_VXmm)mo$K?&1}l|FGJZFO5%%_wz}d*f4PHiIf#QB!@G|MGA-sB$B=pFojMc z6PPYsNmIZdC z7n`LOZwi)8H+(v^x+^?-oPhf-mWufT!eUbBjo7Zc#gwfy7LfhC~{LxX}EGqlZb3-Ac2Wr-m-_NW^^(<={Rz zCz`VzSC|-Zujlu}gn&zkh%oUVs9p^ZCtkXNSmLpd;wX{foIK4#T{#i!FSi!hG2w%* z(<_Ifk?tTy&z4sYkDyGV;ZSl?*l0gc$!DbM8nO1Ue0Iy;yBj*Jr30ZO%_$iB z7q$|EbeH$){$kC5)$10F)7B1ug7V}KqEHFlk;eq5R7@pKZjV2;B8z&&sP-rR1qaQx z$(MQ(`6dOjD{qCKJ_Dy803}~q5t|U%el_;DnM(qNr`6n0m6UCG@J5fy_t0h@|Cn;B;Fl@=fKwaW zi+|MHxx0-p_b$u7V2OOgT-6b50ER-#w_6gnrEH=gri#~0qV?(uz%0=d#~tQUzd{@$ z^&Y~5Yj4%HfdkGlc^l)&iqSQV^1~Ws=I(D7-Ur>?D)mhwj5lA=_#|;^3bUxKwpqHb z95vQPubF5=D(&Z{v~@|G{BVFeb=+b9eqwhIm;+fkCsR_7biqrk{-YWC`Vuf-F=iVC zpD;LViz7PTq^`jesu0irF+Z1hpe{+^h`=g?lUyP%?S{B-IIAG>oK}gOzNmJ5ZEAQH zbFnXNDaMNKA*xa|HTC2B!GpCf_t&McbIk--kB>0!( zF%GGEqWni$laX5AuM)y+*Vy752adO+u(IgHr|?ruiDbtkbKx!n&Dqru!7^0+SAS=p zchpg!k!MM7V49Wo?d-fxDmLUHQn-pg_Q*>Y=h~LrkJ!+*lw3CX60yfLt_!Ro#Cm-jqQ`gVbx_K@VX z#t#oxXpzJl%;R~9lbd2a6H)dOmGi}WPxek$Ko4^kfm2+mw__f2p}q$amYd-` zPD3#V)NNA|7Pqmg5d!^C^Y$=R(F>AcOGQ8C28mWJVD%1f*rW1%aoq1yx98XYERTH? zFgQ$!tXAzQV=x~_t0BYr8N94n9tIKrE`&s@T01B3&N=WNqz`o||E-3Rc5XgH&~XWN z`4_4VtI^-sRuaI(&FCpHZK>t`(H7k!iZ?4+@1E2KIR@!8(Q#|ZwtnpxSl~RDm$`F} z@IsOJtXkh_41F1{7lQH#Qg%Oi^&2^m_<)YR;;(o4;E85GJ>h`K7p3 z95J5waIsX9pXI<)66F|g%-4GDy!=EH+;i0A)DNmO-S0QehHG{Ec`xprQ;(DX7L|P` zyGDjs-(DP}<>2scl(IN2D4v%c^w76c#Godw3+}p6lRS>P!oCtE@H@W=WN$BEC0CP8 zz0Xx&JT#QHKAqF`BX+~U6|&Ashkn!hdSs^Pm<0B?LIUN~QkiWQbf_;8s+b&mn)b75 zV;mP7q6u-iQeDy;eBbXyxcldb4-DJkZ7SpUAF| zx9aN2mY>M{)IH35+qP;|({R192?B=wPxeIH9gRynp9(Z(#7{wQH{Wr|1m>+eHq4`Z zzVr7s+aB%Dl5`TF{Ub#B4HrM30kM&QwBo{oH3rDo2zLoWQ>7_*8<%+4=Cabo$xEAb zp*lrwU4Q?g+uk;_wbUb3~Nbr73bESe$f;4`$%GKIg7XH1&5s)ne;sUx&PE342VIx@4Vf*=4*JwV6HM}1 z3OpAXp-tH7P$7)n*8b6t^!N1_o3F*3>z~=Wqw9ToDY3s%MP^~XbiMJD6Z7q^{%>wv zm){7{yr#={Kk1Y`H`};W@JZry?vY|&{xt?$hA87cJ9L}d2C);9)adX11mQypCHfWHl8=#MG_TgKG;%_pGG4WPgwLvv{MaaO1&820y08^MO zbT&>fob`yOJ3GcpMo$-?0815bwm18Fm8T{z3`Coje@x*(UtQJ$2Dln&SZ-|s$nOl9HS zf|rL2>Kgg;UxgS_>m8k{X;<^g{|i~7??D`@KD$<|_PqbUuw~m2{{=RiRl{Sx0{rZW zm8zsJjqOV-WcaQ#gif#jTZWoNOkd;fY4E_0_sT$$N-hiV1}+_#hVm%gfKwUU2ZDqH zF$ACzP>~G4MMWH{Y-dMe0(zk&?M8sU7|^S-#-h$}OLT+@+qBu12{CPVKJz!lzG!i4h-5^5_50TY3Q(4J*@}JGcs$UJv}w5G#e2BuIJV?{ zxVd49a5TOUn~x#TcUJ!saGAN$OBQeOz=xdvWhHz9nFO3Wn)en#J#*&ijWW>f-x9CC zx_f=u9%IG4xF4CLI$HZ zY5Kvw!BZ1XF1FU8r1nrbyDvYGcNAr@Yb`T<#E10iCCB*flC?;$2c#FDP(#qkztt!S zHl+uS_QlZAhz`idNvUET>9dxm@b@trDGw?m%YrWNAJyF2EtG#B5}y0Yw#H7=Fe<)U zeOR)1b>vF-)H$4{+ghUNTEw<$_rL;cD}t}f(v%P+DCN?=aLN+zVdrxT`0~4H=j1uR z#EtiFEW2ionctr~tMf4Q>VA4>I^x^+J0~k&lmwo@W!zUv3c05(MG=`_y|QuSLOm*< zb|;tn_D3#@%{yN$dx@U&&8{m0*i8W;-?*MeJ&j{=2hM2XF>N!7-A;aqZiX(3zso4N z*tJ z-@32FBVoDI90<}r7j@gBKe)uwB^PY>fwxIfIQ>`Xxp#U$~H6JG2`4vk=i@(k%hr@@%i`WpnW-AZOrE3v2Rn{fDJWh2KI z3i#N^0#S7WJ2$fbQt!|FfLb2Uyjg2t`DSlE>fi#{U6ur>F#n_-X&Qj?&Im6@^1C6^ z&vDut!X4e3xBfKLzY_NK2QNiJ_54B8V|Q;%pmXv!A@@`KXTrk(9YgJFWM@U6w^_?) zG~3yahM`W{KGX7OR0@+!O2uR#fc0nirzS)9lQ0&V%!yx0Oto%g=b!DkSRb_*Gh^A~ zBq08<@i!pM+Ji4He!`%7KqkQQ&DXoRx_7g60EIw!o|=o0t>^qOH$Zvx9DY)LO(IiR z`%U&o&`_4c(+USS^tj;C+cW^tp)VVJPwB-sTi#?jN+|3d&`xi8;+BNH^P%_Bsc74? z+Qz!1nxQq>hIQzMz&(9SynU-(qcaRIkf=)Rgx<#4$ z4SFGO%Jdh7E$$VZf$-*Imz}Z=UF3)DY^nJrYlCPryuGsR=tLZ8m#W=9GBo(7?>pjq zO{9~aZ#u={7PT=ElAjVmr)R$SL2~o9z4Z!}r6b^eR-xoC0wzrubCMP06hc zHs_}r{JTz3EOLR??U+1rYFI8g`jKPO8_bXvtNEFnaPI4r2&-hg#`aOwYE@xV{L;}E z83fCOvVbIj7PKb9p1P~7c1m)qXgd*O;I>ls;n^99;pze85N2z0*@+(WyId{$7+xi!zEU%64XtHrIMc>N3WM=CChKW zTICCXk9#28b)=+eI@1^2Cjkt>Juie9UuHEZ+(F5Z0V)6lxNOe5tXoM3$kSO1`!HXxS{kNG`#6zGsM4h9yC;GD}$hg?K zwsX)c%&TBc+VKmL-E}lG5)E7(ZWNj1rF*P0nWizCs;V#ge(MTh<@FWRyPs`dC5r8K z{&LUoAkx#7JVRu|`s<$%P}^C=SQ%of0{T3;+EQ5?cH!epYY9*<4$&YuQp@Wi3@w^u zgdxJfLRru>OG)ht7#WU!m9Gx0H1*pG$CStl6Mn23cFJW7*F*;3@>LY+~Z-#ZV0A5;&hz)IKXUHz{0Lbw1kumcx=N%G6c(MkAndap zHp#Qj@h$Rg1u31HmT0HHz)d%+V%ysH40QNCNUyF-QVd3%Duc%NZ%_Pnl>3f}8vCTd z3xOpFHp?}}WxvaK$X(XI=JO6z)o{o8$V`5U$Z2lmTpkU)Ubt4F8E|9a`=c*03%h$J zqYm>Fdu8=U&f@kDHCCO6U(<(oI_kDNVA0$M%?M3S~29X9e369C4VBc@8Q1^0Nk zBCUiqLsXmt1j<%bc)&IK8-DshE@d#MfO5k^8tAeU1Wlj=5G_;gii0kxJg_*45IYNq zbdb;1OjT;MNc7MNmy(3JdVQgV4^{UcC}&XZKK^0_lelP`YywYk;n}P;D_T%7KP!fk zYdiWOo3eK`(qU}5VS<|=zYS^1IfM@SV#ylawemDA#H3v?mFxV~0Mik5iVK%IxF4Ul zJZsNC!tXe>ADyGA!gT4UfHrWawkZJYA(Q3iY_uwkKn(#dIlyY^5f;^p16pw+?l8)hlc*h6elfnI3!kvW?$h z*x0dPSt0Fdp6=Zh_Ke<`qG7hy#Vtn?tgCKRa}n-_*iBxRPQ|c25eIG*A$}{Q>#Ipu zud2x2GM9M#(Ab-COSZYT_c+ z6aR4(N+I-cDu;`EYjAQ?AMmb>$I7Fr^@E6P`8~C*lVCb*b|`fZZpJV?5sST-Hsg|+ zX27|!n}hk?rOoc6`*8X%e6c5!!B@?vJ9nJbu3^M5&%CaQW z8oNQcmoH4c#PJKv2D6fcC(tC6DCb+wX?%o1+?>DvweBy5!qNBtIL8tnDVF&{-;5; zvoe6VGWRoXDph#d>NHQ5V&TSaz9>I1_Y~3a1{Vt!{bsc&1rUPyzmfF1CReO=E(a)j zBx=nCkN}<>LH#kuC_^_`D~UN^WI7^S6|dlimkG;F1Si{y6BJ4n>K`c` z1+1}-v6zl?)GT2Uo74Ip$I*2HYo}OtM$JnaHp*(HOqPkG#CBhXt}sLo;OSvvwkem` zC2xx7{fA^y0GwfelI+4HGX+@n_%?Xwr1AP=Evk9rZ;g^gal#8=koWYz2wRr(=U^9Ln{FnUsCbw2}j*kPP0OEDPQjR=Kc{CDl zv&a)!JgbTSb)!5OBx2_mY_ciOOq&;l3em*VI)l%Dh@QCCbd!8%jkgF&Ks3wQE}^ZxRVexx)gnMMd(VDzA< zydX&Np!vn0#M64cJbRepd+{S$lz5+;;@*dyRkryNVC`BgK2Ns{)D6+J9H{}#J0>@) z4)5q?(1SGtbu$osZ@-hd8_g@L--P60$ZDEnxMrv(@^*K+L~rswc8%Wo-*(Y?MfH$1 z(v2wQ+>V4NQ5=7G%x0|0k>u17Ads5Z`PEzYmtSN3RRuI`K72dfak*!74n%l))$Gda zv~JmSp#&l4u+Af&x{pd<5Z@qv)g!^O^KrHhuWhAcUeHSmwPox90wA7P<5^U1=j7zEpTb5D5hQ;^i&c+r7MC8K9-q3x#~o?;pPv&1)UV@bh~ zm~5-blu~es1aF@#oA6lipPrB$SaCDQt=1eXP|?q!Hea0oSYOsbj)6>Lg<+a>P7zYZ z(|2yXOQx^@IfwvB90;G@%WMrh=qR0<=H2F%*B4sx33ifK5-^0X#b4UgQh*-Zc0II#HBEJ*i}$TY&@uBUMUccN3+A=_`?zxAK; zg<;EykCZnnLX^$rfl5B1H1HNOcPb?LF7k+x-guLPFrOsZhp_ZtX{yU5T_c2150%`CgkHQlEm=Dq}b?huVEaIMIOj;=}DT^A5X5$`83#+^Sw z-!z)jnCoZ}8mkng*F_oC`A|WjIR|blRqnk_K}a0f4H_u5dpk(4m2d5*LyBWPl`AML z>EhZMp4jr`il%p$M3Q&f3e$d=`O$7|sWWkch7a~`-m_|}&ivRxmZ3XPS~!stkb~?p zO{^ch#$@01RraZYJp&1ZC>BBGiV0ic>gsV4z|K`bX*<&(D?;V#^i|B{)(v0YuoJRs za(r;0lI(HJbMW?@FcirSeC!t)K1c6p5$6Dp@e5iZ3gO<(+WS=S+Cxy=cx~K@;6%lJ za>J#W`1VyO^=9QS5Jf}9yZxD$VugSLKES0L7JYR#Nik{1Vse}YJB#`P4LxBSD0Gz? zCY)B;8%zR>&k-L%Izhg<&-z|hi3={w-`lS#Q6vQf=ZzJqa_NRR=nkp@1lvHkLiAS= z`x60_sRO+Yct5ML_Jhbk-)B+I*qdnONwSI9HxOmGS48?CtTP0>*Zmd;x1x?|qmdPo zDG}RoDbO0mzs6@Y(bH7}fUQ3$nkMEC94w4@DX@v^q3$}{ijuX0mFruM?W{C*CT;#v zUw}M`&3yh0u3A~&jvr21wxd?Gc@vlaN#B`$Cvs1d#fai z#eW=eaH7|t={Y#)nS&Do`!>T&Yuysd+*Mz!W^MRdwI6{@4a`d#(M=AZKKCGph%sI6 zV#^fzBjbC7To7WXfpAE{Qfwn|cKXl+#Psk9UQssKqHV&>8;m{Gc9Huno#I?$O%U(R z4Bo<$fJVOqs{>*QWA`GEh>7__%vOdF3wN=jbsvXfm&k1?&*ek3T630_d317iO5_*N z)!AP12Z$`MNVfT<2j6du9(fUU#10{k4{;^W>PLBQIb<(rG5&Wqwkx(U%In4W|H=&Q zGH9VHw-gXqfH+CO!geMJGvluznCX_oE{$O;oiRGLFpP~y2+}~^CL|JKCPFXIU3eRiwOON2b-n-ce z*Y<&XZzHMAmYr&1T#=L}Mj28!tICH2W>I#gYi>Y5^|>iKl^?BAma}c+&>f*y!!-}6 zKj&h5>ClvV%Hy%Owx&KYlR^t9%(S319zmUIN;ad^AuA@fw|+jFyVOEcz@u~kv}wPx zz$+;>OmeMxls4D`-n7{_o7)>tn$b_{$sP}PBoRsyQAl^;H5MwccuS@U?cM;$K;kKdGpB6#tt&<&RnFUFC0T*IX$vZ{P z_xd#v(clQ!&#k(ecfbS7El*A9t@}t;o%S@;+bXF|6j#kst6qCJ*)xeHrmNUOBQ>E9 z@#UTeS6T&qr;~8P*@`?INCyKR*~8?VliNVzO4~vP&di#7Vy!(} zKl@I2Zip*}@^+@X!!SNCW;@7=fwxp@g#B_cfx%aqmlr;%{iGxeSGOdVCo2W}-CIp< zJQL5hlmt9V9Rf-a9`|}{W@PX+24@ryZxa%)^GU4%VPTP3B-$L~3BIp2 z#|NUF!hyJ#;XvA9c;~)7UtbR)I%2YKr|UTysFO@i2S>ZaW1=PMH#!827qa|J;BCLo ztR%X6_cDWpp3*q#>2%uJ6-`6eC7$3$D$H#YBXtj|(pa zIEitr0%!^cM9EqeOOd0(#r^Xu z6CS-yyG?2KgPPGHbHl$es|159sN;I|=w$ss^MV%DeZwY`9j~gX`bFD~3NNIw6BA?; zfe0pel@r2h-@BmZtE(PTQIgBcj`f+%J}Ox4la>tq(XdL(%1ZAMA)beyOg8>~q*)(C zYsLLJuV2^-?=87`Q|Kwo2$!Z&Kp-xME=R*# zMS6O1N-MPvk>PAj=w`{M{iwCZ1ufgPd9SM23N38r`{V8k9{+T8HuTn1k5=xM0^1s2{Ci`&FJa{i4bk*5XT<8fR|P@* zROOV6!}4BIPlVazuC+_Bw_+$n_u>Qb5A6JnjuXJ_S8E>P=>QzQ$RQQ6#$};{aKBNv z(fv`6|1+yCyh=Fy|zxuJ32ef!*gysFHf?Cm{p<>jG3UTU-68?7TLeewbX{ zPpzq(QqCTGUl{D%ve%wL%SUwEz`-Hw2)3T(n&}EWVRy7^AOEIBP~CXW86#_;%@~qg z;9goa#OGg9rtQq+-W1u0YFT4W>KpCg8_B^D(=hx3x$X%H$X#2;2p}r7wxgM&>ys>XtDnqW$`%WOzZ|E^Yz#L`iHHwt$!uI$4 zx&!vl{27Vl$+584SD3x(?rRRfPT!RlZk>w+3u(H)yN>6P1omx+P8>Y^0Bn_dc9osMElFsj7iX#SgmS!n)tprXMulSBi2!3zFw{j8jB~ zEf;pb`!mYFT606hWkfaoLRLqh*IU${nYmBOK~yJnL~Ar-56uh@K{$0sK3%D}C$?wt zN@!&=UTH+D$fJuu`U|c0G7mT30ZKm?*!ww z|CreS<>y$huJ!8*l*IXn%@@!Oq z^sU;hMaE<5o8MU+{v&=A#+Her%aCw$V60%XM7jv&N*BxYv}+kfHd-eTzuRvdCy8K~ z&-i7)=v^Tr9n=BYkI`xt;>%I1#{C)_V()YaxN1**%oNG$zoXsj*~nCB950I2d?e(1 z*CpvoF|L!D{~oVzLID9B_5Yl3!I2o8pyzYp^+E7{RY%Hkq|qJ+UYHlraTru|;i{Ff zJRl1HI!zwtt)E%81)+~DH@liTXUq`UsKj25?N#L6a5#FctFHz;W$8d`JjpRZ69%aa zkd3HSGvWE^knmbpvv3sjK7E6H=x8fHgn2rQeHAt3m6-p+##e?08ePMqujZ}eHfq@U z|2nZxVuf$<|0;Z*4vsEx`L8FBg*|3bRF-R^T7KbiyYjBt{_MRK&bdk`#yaB#e)ja@ro}q82wABZ5z@UQkG9MaH)sO7&D}fgt~^ z3`ULCXuB|;t_%RvPs?LGgl5zm)hhY%A*#jvc&+ClXQK)sP!FD{z;alYO<3K;z(@jt z_oB9b5WbGHSo+kdzdCQi`Zdaq@znbOAy&E^_2t$gv1ZbqEo356SecGfF)zAqzT|RqKD#f|K>-yK zKtD^+bb7SD09OL-g>kpw*E zkb&@AxT8f0dLP-`(Om2_nKf^xnE7Z0I2@`C9KlLL#CQ(z1TTn~iS-Ru7IHO3QWU$q z;_eTU8r@f>UYPDgG{3qq`4p+3O2~_ZMceMA@G)uu)^9Hw>x5~Yn-RE721nY>&2MkI~(%=Ps z)3UEI%NLAi?rQ@i7t_FO8TP@T8#F*sbdv>8Dz&y)K!00vrsJIMTbRlk9DIYo(CKK- z3M{<^%GC$z#_ywEcI8%Pn69O)|5Zf~enc1z&E?iRqCLG`M!@*cN5n~yk=PYzO;Fwa z{Pi9&15wMyos{tfJH>a8{521oIKJF4^nRg)YHHB}l29{6DavQ|XHHJM70s@i-Pt#a z7sOr6NtCG>4%G2(DBd_tqP?VVyE)NZ;m?vry#h3LX& z3eht=aYMAAC%b1;$~H`2%~vXvZHXi%`5~uNZWJ^?@d_m5a9h=`sk{r;v;N;dgXUB@ zw&s$a=ZW#C_KW)VFymMH-+d#0WZPFR-&&=oVigWl_LDuk)`reQ=^%o5-`G>{Q<+X& zX2*-gv3uP-R{e_?i{?@8J7#Z{K_ZCPuf6I$#TPnxO+1y8GaJ&S-xKCF+}c`xs0WgJ z!C{R4?=Ws$ zOwo|T`LnC43-|Ux?2e_<-O%sKt2+H|z*(MC$h;apw}a(WwT;o~x8X~!-C8FnI*#Wk z-40VfCS?&d$eixXIgMfuTzXr6QW()!047l!2P-=s5@Pde;%2oA0drc9WWAsiq-!Ux zkSY}}ntFg2D0obMLj#SPY5R`83eR{^0ZQHt<{kBBiDNA9uGCyV^sfbu`IF-p3Gw?z z_xFbeyQEtR5py;sqxg;F9BLmWMKkn$eO;#Kdb5Ic{(e4O#1t;^juQ|rj;jx8-le}? zcZcUHgZ8|YVylLv5L3?sKn^9lTZ0~H2hQ@@rfg2CT33(jb4-05X)fX*w3szqr5$s3p>~1(#jXr z`ip?+ctyrqW-CZWR9;nx73ks~mB{_uO_}8^=h`M(@7(acYukCeuwvVd@DSnk=`?;p zANl&mw2DXh+eZ6y+@@y-9}vL4;YkPe9B!3p=nNx37*>3cp%h#)H+@QRr@=8*asp;P z{jr2<^F;0m_2X&0UewesBr9y3YDXMpjvQaA9*z8{Lj~cKUh`rFV4M;CuGMZo0FO~x zP`Qf-Bf>cvlI+NZHxNN{B#>C+<8uFBJ2|d?vXZCknR=s71EibCIfS*JI`@lc=rfU3 z#YIoO8~eh3v$Z#+5e2d{Q|uBEOGf`54AUerXamE*d9;wBJY|{+QgGP2B3&fAwyf4f9zVS5qOcl4 z449(d&=8@L_l33XNN|}M)9EZ%N3vY_XpN(mOE*XD;(U_Ser+EIr)*yi0-BQ3+H!RC zN1shIo4$eKQhKA)n64X#V~dI(lZoxPaX4{`B$Uzq9J2(i{w8kdF5ErJD*iUnl$~4H z6~Nu#Yb1RlgaAdJQcg5JaJ9gikcp8yl+8JHYG?z|H%9sY9IBk$ z9d)Q3_C-ndP&&h-!)9CiU$1<^=G9V@#eSvy>zKXWhqa#Y>^!?;eL-XX}u{SJc2N>4?A>Q$s5?&yqt-_-J%_oFSd_~XS zZhNsj2bcG#V8qxcY+7X8Xj}8iF@WjW8?ksm_fFKL$9(3COHA59GRyl7vlh9?TP8=7p2(`z`|2-u4Jx3vfGruW zJV@-&dpWUHxBF*%%>@n`$&qcSM=9<@^~E2oX$^<%gQ+Wb?YGt zKUp9x-3Z7*1z+8A_;$y#FoHwBM69H*B1mj+A zB`Bt^-|4@?`g2A$m={T~e6}rb;0IUq5B?4u*va4FApuG@V5BO&A^Zfe@COxypFI8$ zpOcgj@T#J$kNXG}vhxuI25c1_w}5Qk@_(+s6@fAJt#}1Sqaw#OJu7cd1qft5`U1kv z&Lj%pJqYB12Hb8TYb0ZcQf#7s!`(5J8U48~G_~zr79h7en`JMzG`#fxA#sR3sU zbea9}2n^+>tAjQwWdB~7b}X^zhF<2Yik+t`X;4}<0qnRah_d6P+eBAPs=U$e%j}td zUhzyML*W+pZ+2k4&oh+cbA`1FqubWb2#Jlx`b^Wf9MLvS`AkHTV{T?nv6w#jSwWUr zz2j|i0s?#o9@Gi>+KKMF(?^^$-OBkK7~jY%JVA*a;<~=y2t?($ zEWY;3g+q_T{@6LsZE}f*^xGZ-3g*0;(LJAv;KY_-M!`&UluKnFJm2l$Kw$6JPQSxA zysz?5f0F?-z3u$_yWQBUf%Xx5c=>l5kN!TYP&j-w$x!LHyWcxcyPV^@E&b0QM?O49 zoIH7!+LIet@_9L{u3ls*cuoCmA>JsE^kM zw}qT9(AnpNTq2dW`O9K3$9lcSAzq=b)mO$Z@!>7^mAK0}_ALOCx*Ha}gus#|qK9zYWI+*rrMnC!u+Be_%{Ncb| z;!hhhiD=LX)Zb=2KLo#HX&JhU71K_R8DUD;FuYoS(&yDu*#gMM`|&1e+g#G9sgU79 z?>F+SFmq~KJknXHwqc}hFH2jJc(BQ~!0Jz6*|i^Duol~&At;t8R%aBh4x|?uT4S!lEsza4B&ac2P4lyhb*( zfbQ7yF#Y4nV*rgGXjB%j(-vJtiYFz2gM<8@_1b=D%xxJS88ZfHRfaPjJ2Rd7Vjy0| z(~#99f6FZtL={}0NkjMHUXU80oAbNgr}6!K_%H5}n#gugTcT*7hSuP<%%^@8>>kFG z#2T6Xr-(F+q9VR7e9bPc-p-~_8o^&}u*+=0+qNzp=-P!)|j#AJYGUL^CXCLE7@r`1ZTc!;4w|H%p;#?4kV zji)zyLQ#AVFR)@`Fwi(mPV`z=T~-?IT$igxgQC`WQ1E{%MPuj0zUnco5l*S( z&_a?O1b#KtN(GxoY{F*?ojOS(bk<$BHA<%;;NU;+DsS&++~Xg>ZcFK`&PH?wzilnU zZTIa(w4t5E%EY6sBXI387y%S!cSXNc;doD30)_7wAfv3R?_!Zp7}eiTUf18q*K9eA z({1F;<`>MEA?dt0qTDX4JM@zz@r)hwv=T3XI2v=mM{;qsv=ep~@;{GeM@2BrR@mgd z@x#CaWM+>t_uJXPxvTyU0n$fvSwaGb_(1;jXJM5~4S#bS2e`#+PW75}mF-X(?f(3B zlbi?-1E$}*HbhfQY_}W+Nyh=M15}CY+d>hivx$h7+M&sa)AJ?Y$WL5*=|AAvlrba$WRg10U(fioN*m0+xRkX~&^LH4XTJrQyCc@*a^4y=bd#V>^ z&CP3Ujx*Pay-8a5aZ+Q*hz%?dMP(BxA9OOpCX?k4qP$Ic@|QG*^UfEz?cCJhk%7@7 zI738IFL5}L%^dKyz&A$qlrR)|&-=?UFIFE^94`w7mO7ejYh)|80PPIQ{Aw(3z&lht zn#!4yX4Xv=9dT5*mag(!U0$#B_x7d3jG4BxB%^U(zpqCA20WK)q=fMlQ-h&Ha%c&r zXjeAbN`3iLe@IOl%nLf_=x3C0P^%z--=;w|(u;63f*odL4?Rp>y;rTh`=a{X%zY;> z*lhm5%z}Pm*$|eepjj4nvq%Gd&wH(EIwOy}dkV-;o`ulbq7&V`RcXo=EW_E#yZCJ6U6y*6EPnSnvl|${0DxNUFhRFx&!IbUi67iZ_G`Hx zcKM&4f?h+fHdk0QzTgqs;Ir6|@Bi+wYZ(-20f?={Pn!3Ekch4(M7|cg#PhVeE|5;Z zz1__pAW8-^5k6*O$P+H}bvOIlS*os!3nwJe16UYtmwv*#5&tOKuc+CFrU9~MoBs8U z9B;Ntqzyt|;1epsNB!Lk!cF&|Kb{mdN2sI{hRdjmcbC4rQEj-KO4w=g{}YVFz$6`k zPKvxly_)w0OFO9fxFhM%FXtSS?^++EJXP9uMnzz69{dezv#QMZ5dmg-#CzUJlgqgV zj4$$!cv}j`1A;q9Isnbng(!@@CpNli-gs5Cz9o>0ESxf5a!OO150+T)`;J<+a<14g z;`MM=xD0$tp&9Kvq28f81PAA+ioKzL#9mBfHK@*_^u@H7tHF%eH<@2X2_2}YF0GRs zr}0~fL#hL#ovNCaCF2b90r!*x?j(=c$otme+QA`jf~UQ6Kej_2CefzbuN8!a7Ksb& zcb$-!ZnKXz*|GQa?XPzF>eOmDW!q)&IJ`e}W}~y_@g%MM1&P?W%Yn>IcB}AYZy5;o zzHEX21m5U|5KP8_nkdWC3w#}rsXobFPyab9&9V(r>!Cn58e)sj3E(dh$z!72yLo#Q z%`U$Q9!bsNid?j?Rul9bXTyJ}LQK{=EqDNRm5y#1kwrNiuI9lY>3tejX`9^%?QDy| zu$mxK1w`tzoLvt2Ra>}4$d<>>t|z)Tk{$Pa4wD8Qsp9E?s=TB3nx@YCW98#kd4kTz z08gXuB@Pm&0g9;#eTpZ5lpo}~0?i7W!&pH_YU>mctER6*!;KGbCytDtRc}qF+-i1- zay@+2@TLrx+wxkLwRhjsH2M&1A~d8E1YXIuNOb`%;=Ho-Y$<)A!n@No3I>Pqu2`PQ zx{gzJys_fK6Ao;(YeDhYF!R^tJj7nt!*RYKRsws z0!$OdYzucQur<7y8mu#JBjUU|SN5p2aBA!!CrX_WrjOlW0i$j{zDq#)XP2ZV2d#5H z3FXUU7jNM0zo8x};6JE7d)5nn08knkwN6O$hHHUQ-WOUr}98{lWy1gaYEBj0) zTW3p&^CA&&xQD5ggo9t{K}M$^oN#sWdTgKlAKpK1H)A8^AFbOXTz@lY%G|da%#2#L zZ||^c-J)(OlC+AM5UZQ`1enhzJpR~?e#K%wd_O2j?hYK~~fLFTchyQzdax=FgN;A!6U&0^d@ zzi8SCKC6FbX3_33WOqIVoD-> zo!17fu*=;z&|p3X!)}46hjqpI4%-W_r16Nv29{WO+Yj1Tsa{QUf|_l*8Nf)7rf6ay z|3wo}2`mcm%k?+5t7@^U5-83>!&tLM;uoNMjsl9-+}%OC`c)D&YmcYD&5KYu1XGOr zN~g*dkC3~8gZ-UkS$tUnxFb7CW3+wzQgrLt*odNpGPiP3W^fBlYwjk^Umk5m*%vxb?7|XabVZvcT(Fdc~wFr--Y^H}}d=6NCap0dkIe*DJbTwXn!}0*FL7l;8(I zr4xc)K%{r0aa+n&H6-%eiQ0;0j6%`6^&{JWfVkRH9*>J{dgi)=Q+)0`0&}pCE3YZn83JW>hR@Pn{|Qf788rr!x@7Xx2x}&-pJ3mBm2Sd z;mw2icEe^R#%TK)g*nSt+LH0Mxc|7kq`wqVG;dlTWc{E+8&F?$^8)+HQ^I#fO`_na znr-Olw8}D!_hA~cyOJUAfD-%Jyi+J!8@UM%&^PbBx@+&IZbE>f!CMwlc-SB z0Rlt_B!ocn9K7$}{|y({$;rt%XYaN4+Iz3{`5OAeTEhUIXz`PAYts^wjLn&^zIUeM!IB_A8{4oN|u5%(m_P6Qg^tbL5lI zr5yhn;I3*Hfp{;HFJ&$Kxh87PHTOPG%3TWGGI{S09_9>qQT_Z?u>5@A)dvOGl18D8 z2B5W-r5HW5pw7H>CHl}gyzMbmXR=}!SYuJvHfH^fx1SBY*8`cU{JqP~mlL#Fv=s8J z~wx(&Io&%!GdL@~#s_=;!Onq56BeTEH^!&}+jDIhkHvr{rC9;?1vJvA?&B^dEG- z6o32yO~#m$-tB;s6oV3$W44^H4dfWEhFETNosi0~PR9Cgq!{|=d{xdZwl=A1+b)M% z$yA`~K6fyQ*>wew#6_9%P=ak=x9vKV6S9ebki>J`3fVjR3*Fe<4;hE^)iLpdJcLVSaPN zAU+U$%f|-d_l^$TI#bl|t*b&9#VV<*nv3<#--w=QB<~C-sEeQR&et$SqnxR4mu`&A zQL44^Kof_X<5YIH*$%~*BFqZ0sowoud8asGZOzzBMR}ho*EG$%&vN~ewOOg7ocX%S z15^19*WcYPUb%#6F3uE3r{Hv{`Jx^s(E|`!NV**=w!Ay}SsyDa^byv-v;G zgA`y9b--i6jKl;d*Wo+_tOL@f2688jTS52liv7zQqpAJGy)(XlDh%(lPX!!7>I?FF z6}IOLtWkXlIGNzpZ}0%Q+zfCvW%5DX*Xzm^p@1joYImrYtnhw(fa!Gbvo$Ij%2hE; z+>U7k&O3UjI4e&XeWM!iGBJoW9ghCSU6Cy)ZAyW?y$@j`{SBa;?>nfP#R@X6(s-jXbIpchm1{uWimvgy|Pn2uFu@z8LL!XC@Scyb4s)YIxKJ{L)45Dop+Pn4RIYe@KHAf~Hshr)#Qyx}5v9vavdw2Jnk|ViVjby^z(vJkeM9 zR`-Kfo)vn$FnS#>`_0|FR(e9T+>PCw3;2G4lhF6boKUQ zOLmOhNp#wG#_%>vx^tjrQxlI>Cl%z7gV*>(O7e)+RB`3NW@7sjELllpIa@w?q4$f@ z_A6Mi;xA6YIF*hg~+>oD3ls*5F%L9{iTFmdSC2#*3!=beFXh1LXKbHZYR zXUDI^m#vjUEoAtBY!K(Mr+h8TE>JY1<_w^ZAFg4&|fl@>qfntKu;`Opnx5t|idE@_#Kgwwn_lXbv2DQ%raT)r& zz9LhzM3b}e@R*a9b!AtzLAVA)N*R0%)_6X6)oH*3gIarGq@E@QZM-OJC~j-zn3`7l ziuM1|d+nSb6fE0-&(3IW=t1M$*w;94!3@~@cc(=e2^{#OJvA*^#=r-!@faTXpK_hN zN(cX`VgwT;>oFg5hLC1X333_ta8Q>Ehq3x_VWv2(r$H z*%b|GpG5_vQZ~mbj>9J>b_>8HxN6gYp1+=XkH1H6vPu$OakzBedl?yIUCF>0m)$D8e?4Ywk=*M8 z*caWmdvd@NLs-c0#Nt%%);w>i+fBz~X~J z`ToDd6S+(GCHXF^tb+qrB$1A|?Ack8GcTWlH$O1dGGOfjKGd^-C40Cb561Y18onFI z#jynt+w%?+xfr1lV+HDCk<>OV9L?LtjNMn2v8C^dfN+5MulL+nm7mtKlQ_7KfSYiV zEC~Bm@F#LYNS|>4?7sd)sQ8I}TS<0IzkdJ0-M9ydAKOyfS8!kDIk0*Uu))6#J!+GS3c@S!~bju z%V@Xid*XZa2>I692$o8emt$^UUg50VKc-T(pzDUG6NT@g(O1$;4!o0}AHl%rv(A%* zxUsdPHP+0K+UaZ4w3ddtN^O4l6}7I&W zNSM?3DiR0ZKd=VP&802?=xCaJ}-+fTi^fOT3)KicSR#P<|2ym zfju}0+kA(s^<5|9|6B#8>G{bKu{&3a7HkkBaXw@v>v@>l)?YQ8s`SWteG(b|j~pO8 zytrM)!14-G3yH}p z&(+*flDR~&G#kE=y5Ib?-s30Z5HTl%OwzhvdmG%c0-I*$fTh~)KMpl$cU_*Nr>G=l zGq(0gOQgAe-eTQ>zf7q1A$+psms@x0)T^6z^_T4Ie32D{!q#^3u_AeH8-%FtoZUN= z_FS#ehI|Zf;SS~`!8s*-)wb2IE3*=RhG*d+6z?e>FkLQjfgof2)g%>^ zE(2{pPB8k*a;v?wvomszrRkE^QfQSs;Ta*CQ}+tkyf9?dP$O8aI5r0O`|aDM(t?nn zH{K)ahK=)MX+6<@f-Q!$dJ12MFF4XhbvC8RjDq6FmYde^!@zcWfnVb-m~P^w{NmgX zQ#6rx#zUbgYyNTX5sRB6fZiLq)b{CyRAs!^-rxt9VE95!i$ zV6OlWLE^M{C$_#}xmWi?kaf0s%_*;?WV%>IOGrOhc|0JwHuJ8x-$q`5cuyH!{$ zVlgv%wrcK6&Zrt7YLMaWXE__;ICX!&W{M)~vFb8(-?M5=f?aPIWqwVp9LTo6+lA~g zsD4~kBqe&$E;#Mtwz;b96z1)UO=aS=gH=;YZzf(Z#Hye?!2MuO|9$|IOG!g`g5c@d*5;_ki! z2ow;1MR_mS8$-qhKLwo9x*Pw_LPMD=F-oqZLpPr)v)W9Nn2|fUOxr`uKp-&MU|AM*c5zf1VM>J$!lSazY2-{tdlSWf5iG{-(5n> zvI{0e?O&bum}U)T+6SPl-^=b&XBA>ePp2y~TD>?+OH;)*A8Cu5w>Gz3YVtPN2k$dF z8s!}@O=XiICR_rCE}5}^gup_s4uNI;1HN3wseDG?>36*jUDwG^mdfDOc?Gxsb!i6b zQ5WAo3)=H2^sT0R*<$i0pq^;8>Xwk`S!W9;sW}b_c)5`utT=%;wY+sdLh47=v1{p3 zp>ClMMpQTQi=7m?quC9h26NaKp!xSterV*$->NLvC0_PV@;Xm?u5E5(sXKkLXM)nQ z*&Dp1=h#|r^d6X68bIkkJ9%3B45X9zzWF?DGS{T5{|UhHXfQ{WhY_YHpPDuiJYzc? zD&ex$&apMKQfx!Zsd@e4ZA<&k2JHbt>f&pA*QQU)>Fl|#Gwla0Xb zRiX!zT#nOR&At6Lk#jG;n~pU=q}}BF)8t?HR$d{j-}X~#KTX()cxMmoZ#jeO#g?Qc zHs@6(xhc5+rn7UJ9rM^*Cc96jcfSB$Bxaj$RjR3tAS5`8xlQlsdKFb8XBFJNmD)4H z?hSwf=jo_;%~zTW$E;T*-EMd*tw%`*l;^ZdsNN@jEZXR$G0Y=}X@_qOpeDZN~ zzjUnL8&;f@`if-u(~y_5b)ok(6o@$xw1J!H%fkI<1{K_a`f80VZT(9Hb$`kY1_ zUt@oQp2=YS6GShV9|J^0*ma75nNG@Dp8_r^ zk)IM6;3!3uM5}N6+olldE7{WYjlslV64d5Cg9fqh&Gl6a{Ij~PZdTlu-4ZS5R8SMF zneevmm$98yaZPj{4^;guOzWAomOo6e^M@Vr`yyLWfuoY3xgnNLioee+lxD>FH-4zF z^u-i}AUtO-rUhG7mr5(?16~F*D=cY@dIxD_%+cjiJgazq@coY}fH(MV=TE7Ytd8XU zO;oeGV>oi~FeL%VX4F6{Pe>G&WulWYM8|4q3Vd8jzqj{K;qI{^DW?KeEx=~)c1K<0 zJ`ZK$K9jLs513)AV&Pen&DuJCIOf-b0H^o@l1mk7&tYv=F_8n6&+C+mx})V}QjNHK zI?u8C^Jxe3q2jrk_p8dU>cB`tsd&%|?2((w(>8}G@Ep?{OdA>c5l#7F{_%KYhYeg%IEc3HULowV%IA6mE68R{ z_PLtsOu#LvJOocr75SP0NbOKURtaiC;cj&FN7C9|`ud~QjG<~_)@K3#T69q7s@55r zLW-L2XU3Bl^OB9%na~Sy@4Tw548wDvBr7e($ii_rtokeKbc660C|CI{8QTNY0w7qG z7wJ!A&RDI^Ow8;`vh%5g$I-Q#lVbkKtGPoA^YaMf!YnMoLb9w8+Es+3OUBi?7eNHz zx%fzfjwZTJ&<5IE=AG(LMj`f5Ikb){YQ6j3Xl9r1NZm&wuDX#;IIXj%dy4b( zO$OoWQUlYbXe;pC?XNMeVl(1$FX~NJ$VGH&3e;*^&w_HdVJGI|HHi*c$fw&Jx}CyuA{ zrT6AwN|RH2xpa@6^X!TZUV9p$GCDCY=!w>LqVp8Ea=@1wdO@VGWpn&JE3gw5Tp3|b z8FM}SpZz$$O)j+SHCXDZSDc)_?A+R1cS{}=c0pXWgYszT3E+U0A)dG8WHw6(lI+t2 z4NH4dhbo3nK7`N>53*d%wl8vIggKuC3%AoJ6Z%BM39j~G{j&Kw>@|Trls;l8UO%dV zQU*cS|VG+0tg*k$S2(Bn0OAf z2^2#Yu^Fr8WA~FDq{t`tZ`{5R?gWSWB?WV#9$m$faidrdnC)(f`)YsZ#%&z?-;t*D zXcgES=|`3ZDvokJ8&XgD6p0Iwa)bL%4!gN#?9p>A z(4(*-iw)A)74X5JHwGr}Tu-6xFo7^<6S?T`7NUucgyV|?t4K-x@gN@;RWG?>^03B( z|GA9s4%@<4bnBO<~T4anFO~m}t>(lHw0Si60&(x`Tpn@1IRqWv?&u9Vf`W7lBpj;gz86?CCVa zmo0ULSXZL>++v-qz*>H*ltAfQ=0*#i!^q#8)8dS@rG2QkcFj8|PdD7c2~lz~$I%xb z8KE(;?yIvqM#Zi~B{!lk)nqO6&juZ{c&GRAu!ZK3kNY|tjwp0j0Tt8W8eBB>ritKY zdEGrAKCRWY&RV&F36Bo7N`n=wj-?lqR7lY6CfL5xWab&_X|B*_6=_)n;{QZ8UEFigIezMH@x+N{{3q7@3SN& z0b~dAiBkHtbs17xiLl=sV7IX1NRG@^ZZo=$qsIbY)zpN0{#*S@!djibLq_UnfoPwA zQu$;#@c1=w5p`p86@Hq2RZzTBw(l1}jMNCWiBww3pvtWO&TkL9j<4Sd(eUd2Seq>p zym+%rz-BwP+RMC}B3?}8b;8;i?V0WnKiN*{2Bp}|x;CufWZcMXjrr-sxSl?BtUd?N zjh{rtUS_G1I{)U=$F)Uuo)^1Y(1PaMg5otu)5GFvBC{LCy6U{-Kg25>2UV8ve|#55 z#alF9(M9{WZ3G@eU0SJlJbekP-&k z3@ZHhuDTfvSF091#_pX4Uz<9go$&n#!C6v1VDd~&hikXO~IM?2@l@I zap#oc?|}|Pc}tn;IR~(f7SheO8F`87>)iDb3YUV~ko;z_n!vVGPDtf^Y9-0A|M=YU zzvsTMKMaapILWQ;a(gCiA8fnZkJar(EYou1swR{pJ1g|il|3^O?Yu?_%?}=_6-#V) z^rAyRkJnc@rzoP@0RKeM+exO=)PBRB%G-hobWGq$ow_*xYP{YOO*RJaG&@g>tzO8V z{FUDd!T9VzmJL3s`5h+Qzc$G2k;ZE`LCawsfQb7R%BA49^2PN{kGa7kx4U z5@vdQNW_1mxh?11-aTWxYqcpW&VZ?>CbNf8X z-;BZcP{oljt7~`zT?@4n`>!GZDBLfmkh@X*Z>8EwEEFJMyfrz&r2Lf!8cq~}t^>@% zO;=>#4ED)2==*g!*i`;|GT>Nx6Mamns<5fT_W%G+ML}HAbw-X!?(I4W`$TFwpjUqD zsI`eV{tIu%fi2d~d^U=wZW&NoAN)YliH9){@V2&}R$G8?I~^lp8mhb{4`6d1x?aZ% zfSSp5%CNrIK&IB2=h|w%LwfQ|PmTz)4@2B6C?6+AqpDaVs*s^~Vc^|wfkU*1$5FI* z<0}rV;zK@D3*++ROtI7oETLO&g!6Y$(c}!aB*L#zZOHM8e~|G)R^3LL2(!aEqCO$N zoipy5{kSl9CniUfDU!o-RPYic9-H~};j6&iQc``V@{kW4KmHP7iH3`(sw6OpTl-GV37US2GI26ytU(~x5Ax>$cvkgU*P_>{OtC+ z*w(%dF&|kcz=mK6Nxq-M0#L;SoXnmT@SM4D%=E`bRrWbX&YnY#D1Cyu&q-``hkWnJ zJG4Q3V!zp5V~rYve+{`cN>shOKS2(}Bq#N@ zTES^)x|ZyclaeQam4(Z_Ryfk|tk@mmATogE|3e;?u-dTPLr}hk_<#4VH|3p-3$_S# ziT;Guyz75I(fMe^Z;S=!mT>r|6Q)kr0$!klWvAe8H`ghDm$t+ke^{e@t?q4l1gR4h zVegE+QL8)}qj&N|eZ7GH&(6plluyUrV7=~^#bEVYsA$RYxF#k3`oD!UZ(}y|xX&VD z&ZMgJ)@^=V@455Rem;5VX#e*QccVdE!>eU(<67gq| zLq^nZr-+^BYAVr3cMr!_q{1U&^(nVymhVHx zrfB|NjIlyD4Od%rbAKaMHkRW2j;|y^*cjEg3R48u0MS<0Yq~ZezQ_^T?%uAdDuMjc zp;xgMHsnC_^_!thP?ziiY*$gLIA}5ad+=HasbJIEsQ}hg_Tj~MX{!jQ@Gtt3dwb~% z#$TY`+0duudW?HoHm$O|7g>PKS=rM+K9OZ}0aN?CbOnN$uVoRfB2JJvXs#da$+y}5 zXbM1(HGNthPy~xn-+=^a{1*!OaVlwb?H^|iFz3brHS)t{hj5O*YZr*rJNq*2D~l(g zM`jVv_xw7=l;U^j()Ab702BAEO<1)XR$u$cL#dTGA$kByjUdhn^>6V)KU3uLr?E%b z-`c4aMF+k>X~Y{dBnU^8fjOxM-s1{PNoJvmIThT$Pf2-8P21*UdyeUCFGXKn7|^9l zt!5l>C-v*JGE#N(=IqThxKJ732bbk)!adG%H6#uJE~9DNT_AFz&dYoh_hmb2+_M?- zmcW3`^y|K#Zo!W^%8_-oZZy|N`AZ)7iVje`oZ8I}$3{Fbd=2Z{!9Mr@RNHnc*zH@d zM0?EB2#Wmp^Hfy{x5Lbi1o1_Bk!O-FBAJS9;cnX7pMo?q+sbG8Bx(QADx28ygCF4}L-07H<;>HBA@wR}Y z0>TnQMwWm-ubJzTfkj>lSqWF(z}Aw%&1bg0O}oOLj??bGS68x^hAhm^*e&?!s~tE6-)rC zas^d*ir8;Drg2wh%4s2|DNg&fX5y=gK!JCXMZS|$Oy%}6b@FPCI0hPU{`+;Cck<+h`rHPUI8^E!8K`-Z z0>8<4ixB?}f!m~q3v30@|JxlqMwRH3+paLMnTmX`ijxMQ)XSOxDcfAC656s~ruU&f z)5$j{+|>1WxgNbyrwcoEnw#*}4e(sUU_#A5-a5Yy#ZV=SeqS7HThKkLTi;aImHl_> zRE})L-ye9!T=(5KgeTGSZHI_Fnrs2N{!JjPugjOrXroB0PZ|+L8Q4;ZNIY%W#@~54X$Rg}I_3tNE z%*Mn>?iJR1;bo9hdyeBCANZ~HkjJ7;+Wuw6Rk6PLOdl5#f~9#*+6D*>oQC4udY-T> zH)A%TJ!uzC{J2|0A92>s`vSLLMIj~SRkY<62Ayv_Y*3ksMu+mF<08#v`BvdU@ASjX zaQ1P-P5Sn6>rC*F_dN}l2yUYL@eHnBc=#Chb`Q8Am^m<74LeOeJcE61wbsqQ>N!bL z`^*;JQR5!zT?u%BA7a2oJEsgDLcpK`h?gwGyp*OUTQo_`y?VMeUL|3=EiA8@Nv zy$4K+XM2|7iK^sYd|l#PC=_)!a~U8|LBd~oY& z!O`-w8$TWF8^F?B?Gc1vBKB#FM6Vr)<@%1w2Dy{bO|0nv9_i;<=tTJj-Th0&iR79YkE3c_x1vd zv(1G)jUYkb(3!h%uv+g)$d<}Js{Cf!3GfH_&bOC>q$T4aZy+0X^gVrS5uCumr{fjF z{6XQm$Zg(R^CTdcti4taZYh`S0Jk!ULZaN1RQLpc9bc0s8w>_zj zTsJpTCRwuqjdV{A@{;eO&wFfzhXx#mKEtA#J|vHU;=+g5G&lo$vW5}^NJBJ^9pvhv zR_aPvk<>rsqpTQaqvEvPMQPI*p9DZFzRw`xqgb@bqE8jn;a-KSf6`U`1hLp$5 z*>N(aY@Dd+|8{fWvQ28A3wxy!%1dvJc)C(%cTncO?~S>=k&9J-AGjK_AiYz3SW~z8 zv=l=wS{3V$mxmHuif9q<~SDC=DHzPTlYgDA*_q^kd=Y_8SFHpS%T(x zfEC~XwW6n@JYV4$+HsdAQ)iRq(*{k{&1SPVPza*?lsX}2VCi9!@w+V=`kGSGG3Sc(ZbvkppNAMg^^jG+3wX@$H|T+`L6gj{v9{PdbxRiSUs z$PnY*%nh{A=0c!2Zat|HLC+LmNbjvz(wVNX0{9a3pPYrAsc)NJP3x1aj-lxT1V+6O zD25Xbc(5M@xES}HKhaemENh@U|2cpCt=1J%xm@Hhl13ddbwoe#kWI2hYU`>7qy*6f&t& zEyVx+=IY?`uFdh9>Vp@eN~mw6?8(>vmsS8kA@N6BcyUZCK69V4W}_o)j%3=$j$!w! zq2m_QH^%WYLXQjekp2jzo~WW;?nsRFprgECzYGz^ooYCLW%XECp%r<5DMAj~FfiLP zAqTJd!A1~D>F3^TO#kk_S8`)-W@+@LV+?4%R1x-TrRsuERw|>ynl5J)V?(@Z_rPXn z>E*UB3MMB>*p5|rM&BOwm|D=X$8DRU>L&j8)*n#q!&>Vg+Ktc0etZ z@lGNUppc9QPknj{!jcRL@S}>m{3u6wzzVK2zMi$d$c<0uMG>kM2B*{mhQ?SS=6E=}3nNxi{q9 zQQzTyjgjJ2hhd^7oSP&w9Df`JHA+j7idGtyATMe)kgbUmeuMCFp#5v={RzDiMpAXv zs2A$ybbjJc?pu{$SwQXnsMGGATd^ynS2|9EP!Uq!Luq(rOfq*%jbfDur(d$0BnM^< zxLyknI|6?THR*5!PzPWc6L8qN;U4ijhkh~v zCtIhTsZ4`gI)$xTqs@)7^|$@W*o<7wEB;5+>sw{Zt@qcbmOHZvx`Hk2R`2)tBwCeL z8dYLOUp8=eEUDA80I&Bf*pIvC+?+bZdrNS3h3~5=B*{W+D)qwQN(}=J=r;Kt&m2Xo z=5&8`vt|JCqIJxu=#m?BGv+&02AwN*Pf~Q>wq+7CtknIEE3Y4xAl6+b%5>+Q~#Jz z(+Xt(;e?!lKxd0BiPl;-exyP50LD_)JQ)i66ZruBC+;jyEl&&3DCyXatsa(E2q?^L zp-%?5kSe>S3kuH(2}}DifXzZ5xps`y833bl6V&(7?f3)2Pm}#QW>{IQ-wSoqd6r4( zJM&`icSk!?A1IcQV)4V0h4NRa=EVqsOtgsG1Di&D&$S%dmqB-DD*G+`a{vbRiMg4l zf|fO|=yN#$64Cpn{Z~Q>e$A)d8RkPY#Ui|$&#LoQ`}YXIXV-K9qmLx@wX{vSIq7&9 ze!L=`-L@9+431@A9nAOMhmnDGB|E|%o8}j}z0I_OCxHCBCy)q&bWbCB=Ew=Mmn@b3_Ap zlsW-dxV9B@Eglb~Uk7;=*ssx&KbfvC%3A2h4R8d_2XW9S<_I*^rJ_^!%Sm@k*lNi9 zIEZV?FhdK^hooI-Xg^Evs+Xp{2}9z+&zRLFmDanyk`a)34ub79E^7=&9z4=j&fIMi zsg9JLdkX?aWf`)yU}tP8^RRVD>PEyn;ye0BAFk&Di8R&qUPu~_dmzJU@T;}M-OojR>NmxR;a0vLkF%n3UrMX+uKN*N*@tf!60 z)l{=9?S>4RiJG(FB{bWRPQdUNfrKraj)19yNNlPnF@Ap zpOash5wJfHv&@4ZSfR{R2mL|y`zfeLUTBSS`C_Q1sQvE#2}a?+!IC&MijB}!szva znOdKb39CSYx*^a`+@$F9AlOi0l8d_BV3Sw5!h%+uF4U^HsnhMo@-AMDMXFGI6hF#7 zNWgESfbB$}Pu!D39(b_5o9=TK84vwJ27%JQhvSbIK6$KueduQiTY2c08dUd5G#nWV zNJ2^GpFnGwvTlwxD&)67I4mhMd8adueb-BAV~)Isd%;H9xeX6Az4jZ=Po4&HIIeOw zZvZ=&AD0A6w4v>x(swfXwnCGN8gy!>Ek=+B<#>d|uj_Sd-Dy={P(elbkGa*)N2zd3 z?weZ4ApMU)>Eq7sx613fobyU6hrHhv4#ixko*l>Nov6dAYdK+eQ{Aq5k)A}=VRcL- zIev6#I_zDV*%9I7Os$=rr~ zMgLXifUkswp>aq_%gsrZh|jv**)$DbBrI>#MY;Zay|93=IuML7L|E)(E#z8p<7i|x2Tz?veK?0Trcam zl0*L(uX8BI&KL0YoPw`ZK~786s1IsNPDv6lDs)mozv&A7hK!q)2C-{kd56Ao8#X0V zk!mPE_tAq#=mLt*HY%!8HSCT#q_C2mMao&I6K0#!m8TB%_4 znf?Kwth{wRs~diyDP@NaQ~NyF7}!vydTnkwz1zS&$x4gwf#JtuoAdg&9i=kVmr+aW zhxMP8PAL|Azj=Ei89vh`8Nd$-yxe6s(MHk7lXhDN^FX)Vds>f*W1y1@pFZbwNM|{; zh#gJYU?}oZV$YqfQFKfNF&r*k83iD_t+V=y{SJJN`Q!p9Zc!a<*$m{{&bElR*kT9A zcOHpAvx~5hcy~(|SDVoWQ!Q)Cz3+@TWYC2`IUkM+mTZC&GpB!9C+@T+>-hH?Tk<`E zLtQ*82|8vN;vmA}f?1)Mxq`2F_F&RBuE4Sc0M!p`dR2Bl;l0T;Mdw^z&+VthrgL9y z%k~#I*<|MDT}D5&34q$)5?twWnLpw*rFf;MB$*+FMg}D)Fevgq-d*WfDzF zv(HuY=0;N4mGCYX9616NB{#Xa&_-#_4XGZ2jdP)K+>x`ZU!&`QVsA#dcf}rnWN+=Y zbK(A|=j|UJm-Yt=G$%zjp)@J@H zNjttNNYIVbI^iOX$jU7Nn;Ge$y6bm`12mWy|cjW&L68XJ7F+2mG zn5@z3nt;9*sT-OBmO)znZYL2SI{DBKDhWs5<3HR1hz@mK0u8>;YIHcsFEA_Caq9g3 z`$*D?fhY#YN|A_4>@Z#Yrw7%U zoY&)!$T%MyFXxl`U8_&r*YQrF8k@0BhyZg>1q{>`b++FVEK@XhmN)+|K+B zt4xbUds8)4YM4veD1t9YCn~|UVT1*Fwl5^M-X7kf44FM)di2yGjfBGDbnUR{LWyGi zyx5E4qMHTbSL@sFRRW3U!R;TRSwSV1MZ<0(mW}ojHuW5<`Dzbli;tt)Q|z`kX55VJ zghSMp&N?#U9UN-5Yy9IEJp&9mno6TY|Iu9{TM|!Q-K`3qOGeV$Y_4;1{ePWMfkG-|?0ndsbPQ>pCI< z6LrL3YgvBnsP#=&Da`o@fv4GXf2Tyy6l(`|Be? z>xS1|;M2A#!G(RWa;*``gS+deHsQIKH`BCD`lKF}-+U#TN3)DYRcY8Oxdcf~< z+)6@7O_NRN%*3F(RQ?(t`_CChg#X|ORYI4;e(Ev8k3LuZz^K_FEJW?=<2c57 zxC^3vTH+T!v9s#Fx0pW07|S2KBOqMNpGVdgunE{lgF;j z+FKE+Hgn7%c}Ihyj(UOu!Y`~UYWxs%1jGq%i~=KL4HIX8@?)*Q?F0V=9IX!8PSfD* z%Z3}Tc0(1@EX}_zEO~c~r4H$w+2uU+Tfp{o--w-R~lM z=VSISF&B>}@%w&!@!MkjvH;N-brort@f5EwIdziYTaDZw;`DFXQB_aDj2vRQ195Wb zftT9RGCQjbMSjcWtbw!YV&Nr@&Tg^K13PFg6j6GjZP+9RZJoR{2?azeit=)H(fR+ z@IV!LnR1G|58NA@Aor?x zLE$u9~P%A|)e*PHy0M|q~nUX#`e_c+dabl=elD~Y|zN#<6ewy9neYO~l zDaGi1#-&6AE;)<*yzsVQI^sc*Ji^a-otL6gKR!@|J>wH03{$$AozrHs__Wu4awpKl z!?)108mZQq1G&=eEvY~IY@_)+d0ziF!nD+cPOI{!t4UFZmI^Al+GF)|P@R^t&~aA) z-lQaGcvUX*<|UvZ|A2K8bu~%4dQv@s&)&|XDh-sXYNer*kKxZi;!x#04W+aupaR+~ z(t~RTJo=-qu{t22j+3b}P>jCnA1{gY2Pj7m1YbVX&~H@*rLpg@7tbD>qeq5*zUjip zdf`VfoZd$}=|l$x)WW`2TO1~;y_V8-XK`F^LqboLklhyq)C-8g2DkH`_X@(2wOHXddSR2VMaxCn z3HxW|GwHB@@eJj4er09}Z>MMsJKxQG15>2MT~hzf1vk}gR&T&k)%jkN7HO4B)!}vu ze3MnjP;U>i1>GwvZ@cE`?d{3Q75YtmvmLI24kz6 zmLIvQy$`Ky8g-_9qI^|yd##nT=UF&xCi6g$b#&jF5~U>p;&3pk)B(LT|AoD3VpF^n zK_DBes2mNdC)w%nBi30VYaNN=c$Q-&As+&OEy7VPv!HtNlP=I$KX>b!pP?82S5Z|F~$l(x;Hxh)-oQKGvoSd9LB|49)w`^M7MoL`B%aJ^j8ue%|ww_%rs{WfJyU}Uj z_U4SR-=KzVFvD9nU>mUfs`K*lzWDyD^Gcm_C2Ai!Ig_g`(t+^Nck}CSA}l2B$xsU* zqR(?{<5feJgnBNaoui}Fj;B2PqC#MU9=CV88OnEFL&;473iI=0A9XA(4KoAz0THWj z=*{btw_r|8%NGooLj$&ASHEt7%f^k;?44+oVxQO$54=5YW3rM26)71PnBiYQWoYBZ z<={H~aRzqZ3z^OHk)1l-Aa9XPJjg7emDk}*CFUtc?X>cZm^^n&^v0*9k*X*tskx4aa=Q5`&VW8**9mI;f>#X zzME`1Ww6+kJ>Z3gtg1?-)%*jsuiq<7YMC3YdLzI1$^cyi0}`;BY)7c ziyiUOY?8I;N^gyE@akTS(N4|9@4wMO@@5(Pq}s_G9X*`7Q#=! zz;0Gdf4pk65b-N->Yt`xSHiWt&NP);?cMtNA?9q;oa-g|nRhX7tHz=E86pwBhF+C* z2H%;ZcUYFS!D`rX=z8&HoY7W%46a9W6EtTJ=w}L1QfZIQlxdj07xmFybU&g=OdVP5l zg93XGn9{*L&I`M`K5HK=yYkK;O7=s)QbnJ_zOD-ZVe@$6Ce&!j6Q~GOk+N~Uf8T9U zIwI_7W?cRmx08(s*b+)^7WL?bfH6GNLdb=0gy7!Ya#7h`d z&b*zSw*qG8c97eq;dx}`1*@wOZ(`>L=!eX=h&SQsu!T?H*U^i4;fopdS`w3R7lz?^ z5oZzWW+KCFL)u-h8NbVuCc~{a5(~iq&sx49y z7Bay~@zD-4jWrcm&0tFn^X?SVGv89AG%WZ_<{~JxKPJ@jshiW^2-eI~J@V(PL2Ikm zM^6;MXXsz_SnL$eSm{UoEOgs@n~X)QoTj`;J7SC#Kn^vZpZpgT_AT!-FF9rY%=KpA zA#4*6YFSV*@F6w{G&f23(8>M>_US`N;6ip3S?L6OJFtu@g&IS+-EyVAVggwrtSx(e z9R*b3>tGFUNgeqf*6+-pV`OcJSfX*=8F$EBj&72cO=WS`1vj=Nx*uBgL}%o> zoHNNYZW!b`j&Qq;E6N4ZY9ojOK5Aq6uY%c?2IUa%M)|4q&rv~0^Oa8Xj>&|ps3U-2 z`6Xhcwj74}2@xS3)XUhi2zLiLucvw&ZEsR{ed9ehWzS$EPr^>X@e7>^gk%#cOa6D(y{yED z-^hx-HrPqqtrqA1pQrB*Xd>(0*0rD_pdbjCz$yw#k4SH;Gz&#VdJ{*AQbXt^tRNr~ z6P4Z-RzZP;NUxEW(2<(ZOMn2O2!VtU$`|(C-}mQ~d+wc?`L*7;+MZ}3n-G+FLl zC5d&UXojlem6y5p1L%=zgB_8*duSr_%fCKpO(NXe;a$2SpX8v5d13Hs3a0pdEV*nV zV0;|gG>VP#ozvE2tVDWkf)4e>xe^4gvDR>yI6J__=1{$ytxjw- zLAD3g+Dr)i-({f|tA;dp*rDsnX;@fn-*nZaKRGOO9ZsQVZ$h16g2JK(yb6=qY+|+vpl%#6qlI zWXNzH?A^34w^s4VmQ-_W?(LwbVCDl+i>pBP42qplwhyMcdwE@11{c+aC?!#?ClrR=Nux_c;`Sq?k)_hPobBf-GOl@NSG^5yG2ZBP z8O`{Tep#lrn!vu54SX-wC_IJaH$zuh+K_q{K*Sg?*|fBs$1@H(0q%}q1+N4c-g-aH z+q_bt(rd#dfW+@#{v+5g2Z!0L`s5$QN>$Z6o-NrUbzSasveJ-57Pzw@LtA0NWb)7^ zvtoo5)=ROQ&QPI0oatk$o;RwQ(*!HJx#mdovy78Kt*oW?B`H|O&5D88o^nfgEXYUu z!XtR1#RKa-NUVAj`X`j)$AxwSrqtFz1^H;W==UP}(5oGXi=L+#uMO@5EdPeOKfpJo zKwV(+C?QPQE1Q~2OM%aqn_d1Omcq{VJNB`C!o^wD`Ov8Zx2ZVhprUu%q@=32gVUp$ zmr}v=zw&~*ZFi@Cm;3^&hk`~E)~5us5ubw)$|a5#q~Yty3B)MON%RYfAd;I6+3DL2 zkgz5VGvZGn&*{!7!A{30x2W=GT|lU|a;W&OnlE8~65^KGNP04{hTBCx&7dEjcp6e! z`^ax}1WVwpD*u`Y)|RwH#m1k_B##V5!!}-6d4t=h*3MBL4{=K8eBfR0;mfOI; zy-iV^->q<$D_1R?W*+XKnywKbdzyaJcA$MJv4v$b;OW-{^4C3w%6OykcQAH7f36L4 zh7e6|d|RwhDS-Wr*0Ha7SrDdaVV|y{>~&Ty=D(2xBlW16lKs-V5(qhMeRJP0EWhfX zePo}Cn!iEZ5+_{d%*@sKipxXxQ>O?)E^zhwX=_Q05%URpsCFSFgSuF(K6XySVV~0` z(7FXOJvKUX~?S6&~#aN_98SI3V>Ol%sM zMg8sb$n5Be*6=HrKYYK)&pYOA`uUF8=||s_E=ihwZ$F`I_Nc|kM)v)~FZq8=xP(p2 zx&BacTM6{Y_4-F*EmgtA1s@`kotmlHy^lm9_k<{BN-;^DweS3Sz8fio>UfN{rMFuX6X@MI?#+6YKk;X{r_=VX zG+}R8Q2HT$O*uBv*O(k?RBDS{6ZR{<#@pRL4JV1wI(KR7heacneYkULF!&uF+xH~foV$>^DOHv%{^=Ty+;}aY5U&Npn~*A z_R}YVw!W!+w?p#~8nGJ#-`7qPqJ4Y9%@z3$ODN~oHa-g4ik%v60so(c%yG^xVJ7Y)>n;sB|^%=w#%ul(lC-#0~62>>%o&1Ls3CD8XmW#$?ZO6w#)6F!wi zWt_h83oG3KLK%Oy`6gVb6A(?jSJ4p<*I9{bVE$nS~Bc_5A?$gAtwWWz@k*N=M*55aFj>D3@FW_GJb;rBE z9#v(6rz>%NuN=-(p4jKS^)B2)DlW+_ojg%xAn!7*1$j^Uc59$l;9?s&M>6o;D484i zK~FI9?_m6O+cL~DkoZ)ig?K+H0p{xBYLXhZug?M31i38tNSF@*bzt;tIaf&e?J+G+pJ8|f$=+wZKWK=1H+bCBXoU3rI!IV=m$nGH zg0*Ucs>Vp204_~LV)_$aP$oGlu2psaI3UcKh5Ibmc^7_Lcb6q#^^w!OVPSUz-E+9} zywApbe~}rgfA;heS6G+kMXTeOBR%GC!cJ?9i2vriP8QnA;EA>I?^((4U$zg5nsT{- zi3VshmaF`@gXntTk_g0nOl(=uPyWVoudZbFL+;ZfKH4V&%|L|Zk((Y0mC-ftQ9wpK zL3T;g9}+Iyb2nQV`AA$9e>-T)0(#%6z6Rmu#KI)j1+PKBwfcPrMk{}&uAQlUWy4!j zqPF^(L@)fQ&eHQg4HAnZDK0@hq#=c~TJK>;x?`#{8cL0;Gvl*k!q7<;Yj5Hu!$HWd z4wZ8KwYtyYw)?@7G$ypJ(sWaz{>#{9Pu@$s%3pV*KKh4pZLY`f(0LBw`Bk&b5|w{DpVwjiqdKQ2$ON_eawL0UhyO@+<@ zeZsQkV21)lxo z7plyj`67T+kuMhx4tH3S&xKaBFp>^E!CT8=?LHkWRat`C+|W@o`K%~lC7=_AP7#YwPPJ)JgZW=yyU@QEc5SPZe1+%CzBy7= zEsIeoiU!>&0-Pde;h@jYL zrnM}Yld8;F)1P!K_&|=7*^@JujEKpFu_G+qnL`T`5-0RYoG~*D!{WwV!@2A@x!Tq(Q^7%z|z;>vn+y}pmBE!g0)zpest%`O`zzNxKhu1(h zjsVBR4RaIN2{Y)cNISVze*a~4$u)u5zke3lJkEN^eP)S^+fK6eN}yB9!JC4g>&mB5 zMPiaXv5pN&Psi`6S2#(}kEsqxGPg>f8q2|ao3M2Cc`8rXANCZryFsYR+hY>TozK5Z ze7kgk?*_C`a#<`^M@9dSu(g}^LTFfg1mG#K3x{%NTqL@5N78Pp+)dpKVzG0>-vhg* zyLR3PuQ+daM>TziQAh@s<0@Ry2SEi9?|s6kn?CNwI$T8#9~~PO_m1x2&N$|Gwf+PB zeW}fUh9g01s66`=y~lE4Pd!XdAHPQ$V5was-bWn`>Ju$g(CUp*na94+7>q{%+q$V5 zvfp#$j^%AY5q>Bqe}o!nH2rC3h{>9755Y*8-`5?K4CgKR%A?*D4y?@_Fnw}!zM4pQ#b}z&QV)#H~8^* z^6qNRDW8y?7I50Qcl*-P-f{$W_F9B(+Q*wyM<1H_c%7(C3bPeA|LWHr8T^r!yZle) z=*NQNtlf&I4K-qoo~ljQssKcf&AWwrTm09;qIIae2&iqyQ;+Yto&Nh-8ERPuAO3a_ zHhy_eHD;YFUu|FmGjK-{~Gk~ znc6QFn7bj{*uH=7DZJLOITQ05Tq6N0&^|^MYVl3jTfP&s^H?r^XR*@!$MSg*Tm}Sb zw`{Fq-v4DWJaE2|#w7svT1ip>aS~qol>Y8{W8a}*v&t;^_nH5#LLTQ6Kb3m$so18Q zJ(P$SkdYxS42I$c#gtARK1L(tMQ>jOz~-%pSd&=(*U&$D4>%{CM9z&dXw3gL?6C2h z3xi@2vmt)}zfdFP-h2imMr@TJOaImjBmKxmK`38N5&7qDJnW%_wbvY{c|Ns^2vSGa zC?yJsYG@N^S&J?LKH`;0eiGZD*4>*utj}86UU)T+j8d2lU1yjuj=o75k<);y0-zdF z%?~iyzViH-lxcX$6zyOjCP>#Z9J?>ey9gUpnGm2u zsRij0PCAz=zH~ASKygu%JZyZBWL#8~7|5#0F^kovcS}6w@AB$Z{{fvFAdhz^Y+mZg z%ojtQ8kwEq1~{#nVVvJw3>(ezPt`s(Jh3}(C295I?@?7v9&;l%T4NBGcKWzaGyq$( zTuthzRJ?Mxo}9b;cfPoILVQGX!DUF+hHv{(cH)w3L&_b22C1g)$QpTR6*R%JeHj%Z z^;Dfg_EneA<|H&$twc}*@<tP$@ehw_sXnw)~(?4Y^_zq;yRy z#WN9#kp5xl7fro{{-bAJnKMK?Z7KAfbNc9ePXnKQl@_e!uJZkaCTv{hOkLLv7Q8d; zS%RpN1FH}s>iSj)|fMRIUNUu==a;Y!YsX+6!6sc=y6Jn*yst$G$Udq zP~UDfN84oEtJRofGnPyddy6BKr1~P5t8^l*MoBj$arb&?BBdW#>0+chOGwT;QM)u1A9mSp>F?!&rODf{Q;^6WLrrw1@E7*(aJV6FG%9Wzh6 z6(uHnaO-x9v;)U$D+d?XI^B}bBB;t|t7`bX&Z45rUggFT8b1_EEOYtHFrq8fv4I9l z=@D;=a(Ak}>Fn2fPyS7tykHw2Ua<4(G?9mp!{#JsJ&4reCss0bS8(7NYv#3bfYXBF zU%1OlK(2IQ$Lt&(wtcU=aDU;(tal5l2{;JPpqpRz+(5>f1|A7QkE>2)5ToNFsg>f( z*}5LHdMo(tiUrf4aBsMiMobytrFGD?k^&tTc^NtYoqNxEIAb>bsu-AxjP;g#PmYIP z$mSYE=cqmh&Q+X!REM1V8B0Bx(a&%Yls#j?Q8g2$Q+L?LF@a6Y7~cq1nX&j3u4Fpz zzZ{VPbTZ=spoUkaMLor&6I^+v^;;b3cohRVMU4K_7(#!4aZ>Z=`3YLL2BGA}NP@|T zna%pxCzHAO&tUc8FW+qZG%5gzlhe0wf(k&)))SGAmU4jFgx#7ovnycIVjse+F@%Yc zvI>|;0o2B%cjO@MmD_#wA*769${H2zyVd^_!r1mN1jn5$NkZjSWOE=jFN|RQrG-1K zv+jF^p8~P;TnTKMWO=vss>qz0w47ekHLN)G;O4x2l_tynJO;s|z5-JFH~+8fwfbb>mEihjVcJo;@=5 zh|p9kvmnw;^fdUh9D@!hS@Twrb-X_BOGG=VQA$hC$_f@jGO2;Z+$G7qT3`I#nMk{j z*{t*iKIUlTPNbs?={)!A^ytd8>v9rWeCCns7aoyijHkI~^+LEGvA$Mu*SDM1FYy;- zE(A1csf77ZtBWPJ$6X0YYnEM#WY;l&j;fj_^lw-BylJt9T7QFIXrGw}O_0gAGT*$; z&Lpg7JV(z+nn$ix$o1OmZh;;BE(~(6d@rihR3XkaY_Z@tsTI=jv|t6AYeuud_Gxx@ z)sb3t-dd&ZZ{Y#0Pz))pT2(Kjv7iyuY_rTWpPdHSp%nRTdv2N6yhV>!Wt|O$$!W7c zSxFOwmQvNM0zOUT2+3!h1wE)$e&Z7o1FUm2L7CTl-T-rbLyz{x2I6R@0a|0{xK9#~ zFq}QxCIxNdEeY)2TlSeY4%&3{XzM?GMT5a#@%qvPU0C8eSRIc+MX~Ov;+2uiv(}zV z>~)@YEOa)R`CzuO_b8HR~a@!#)k62wymY&Np1PZY8=eiC^d7XHNqEyanh_1GVVZ|7XPa9;oDC(3YO}|BVC>?e?-4>C!B|POz({4VNt} z64%=))2oRVY#+6!T*xy|x%uV5CX+M3m_ap}N!&_dB!-{XL}e}yr22QNwd@P#6R`}( zB|1Lkm<>}lupWSZEf{`l!eEJ{X4S2wyG3?1u;ikvi3;Y_MXIx* zu~@7&H7qe!aC1N+XGd`2FXP%Pq!?!hS#4%lfFIE`3dmQ}Zqc$|v1AEn8!L33D>cPSC3 ziADt+dbnym$|LhX*6M|WMMB(qx?i&yGC-G1(5V)PwY)|W7Esj^Zif&+A&>+>BN97t zs~PLCG?(0p4LRAK=R??ww<+WHH9|_6t3#JaL2VwVlw z;L{0S)n*yL^{78BJX*d1HZd8NY)*ivreh$osa#-a+nG(m#XbrR zSEtie%*m#1qJ*(?MQe;`jtEeAA)&BEx2o*3EZnVi#c)8tcI1}s7DVGOrjk8sJv7AI zZV3%I6pQl_TrCE0I@wD$5i{2RMicU5s15%1xWe&uworz=Qtj~hK#uS=Q(0A|=t)7J z5&m@3NkLt*i~y3;*b-<^t#hzFeeq<^U$q#GO!gwV=EW0xX+7ITwjzhd=J%h2k25YX z(BI?m11Zohn0bl`{jAD-ZpQY*_X=4ja7xFaZ`Tdx-0WJ;BWcYVloYr8>PZg549OI| zBNA4fB)POg+5i`1A1vyVW40c5hMVo$mjW(0K+&FhElrzn2zI^poE>tAS_qA+oDsgQlIzFMbw*z*BX_U-R{Q@$(>w?sBnPbv)m z7gi z!1}pfFB+l=B2tlMPz_J@35i*ain*CJqfkkWab)JE@-znxmU@!`-xpQ~O!bVvXYa$z(u4!Ak%wQQC^d0Q8ozt=~vc!kR-s+;P!T+t1g z(hb{K+G_TSCO$sksVHvCXODX`sfXnJF{6E#oUYgXZEO8hHgn>7ox|%pH~RgZt>cC) zv4WSsa7o5O*3-oQF&l7Y{%y;P2{qOFbQS*(r1!c$AU*m z2bWaM(}UB9fikRRea%f=N}#K7jfPjv_x4V4`-r5^M@zxu?^f?bUiaClxQ`a)>AI5j z%2%;uo4=A}K2Q0?rB^Yd6%KzS>WQxKAwS&Y#6=UvC@7WRHQTp+(<iA8)1>6N|pWaL9X&dz7Avh#+}hDw9!iVuJF$3TPL`@2e| z`L0~`XNqJuAfwa0CJt{j!cjC$`(MOB$AEJODJnu#TiS>-q5@usUch!;eSf~9suk)K z*nP7+Ch#~{ZbQx+lce(67U1Sppy4ARie>S1iTUGRf`9BA)G67=4T-sBig;-5MBz{w zgg}n^V3i=DnyC1@cv)=#8CKVp{PCDFS+MD;{zLP=uTWmQ2 zhpTYD9yNa^RnTkC>g(*{opfmxiTKOI!%_Yhd6GJr+vHZ;*)C?NP=EUOs`!$Sx8~D6 zD`PLuZv@x{jM)$$Aommx|nla}q)L0LoB1=I@X>Cmm zuI&TQ9bJ{f!V70R83I+J(E;w^C2!MB%iY>OR-f3qf|6mCCkwRIKxchfQOnw*RR><) zQ@INT&8R8Xx;3+EW4C&UUe-5qK4TGC(b<-YvO^VWB8NX-aeJfaq?cH-LKc;R^ND=K zEZ)WVeYUlw)-sBZv@iohhfl+OS+6J{Qh6({~ zgP6b(&NfSXshTDi+q#1z7Svz2gK=4iYXCXtYmIR?^P(8l5-u^pR7<5{SGRvKyr!x8 zzM|{e>lrA&d1(qT4yE(j%IGy|boC^+S>7B1-_8sr{R=s!xq{=7Lyihq&4(9W$d$K|(B>WrB^;ms#i*_Qyeuvt|k>WgMJPVikemE4JC>^KtsQlLceS6dTrqT_DYy>8s6UkPNQRG`R z>bfRjGhb(1BkCkGiqPP|q-LRTW_?r=9E$F>Kuy+eMO5W$BGZ&ud*w}e{*M#JOwqjdKWk?Jk!m)0f7VH|sy@we22)NH`s5Z}H3PO0kqsE0!N8^->f zk6g5nU-vivWD9VBJS;x2%|*Y>mKF&TO@H@H%h~q9euApis8y*jh5{70hKK|=(@)D> zHD9;ht$}8bPQ5&;B?>mdi$_5w!});=SR9~04@lV0T0gQRSIwu4+4*&3V?Q2VTN&md z?8QX+t9nTytoK9TeCL1(KNVVC4)p0Qvr61q@UCiU;FxF?8hw9G~_9%y|?BpV+uj zXUF5P_WO+T=e1AImqWiQZPX9k#|P?Eld>YPlfS}Gg^6ARC>u{o_@Ot4PCWJ910nW~ zPsR?NlK|QTua{P@#1!x?LoYDB9IgUwmIZ%fOM<+&R95%un%YRJG<2nsk|ri`{L!}f z_#XVHpErYD%rambQNR#goC~wYc?JF{^Z<|7GYZJ8*A2iKY#$H4!9G!a=s~pa$l)#y zPTs|T#6lnS+vTnJGHMQZ;OEI5Ya$|3{Ai1Jdzrya^5rVq@qnsv*I$^D{6@p0c>c{+%RpDOafN~m3*vrAJ zR@F?JF7({R`(FjX%#l{sfD+)xRX`<)Bl!_UVsJrK{P+3^>AaOnlt8!uPkAHQO{kwD zpp5jNo&PXuHwz(yG~`Ar#HtiLt0}@5J;u)Jeo?lVtEhDv!blkCTE~LPA);8|CD`WC z?5?WHrK?HmLj94DVK&7|ciHCG*^V72dwg`TNt9r)SI($|;`_MK3n^?XznrGRdo^bptTabuU zuTN=CD@kjb9T%!GO=0va2llgN5^R!HpCa3zA(&@~oVtHz*BamPS?||E6}rgFCjxRn+y#FS6rq}ML&0cEJ!ZO?n_57*ZyIymF#k_crB=oe9k}_b%r7; z0`GebnNUCb4UHrrGN)Uai!B3m%6)FdIb{rk=St86yll6*d@{n1A%T6h+AV5wh2q1G z-6u~Ld3qIB*lz~SQWBm^3muCzuV9dDw0Gov_VjKhAzs}s81)f%oG@9>TIamZM!fY2 zL?-xetl0Ls9jW{Hj}UoRKh`b8%2O2U{lV8~>=I>X1l2=C(7W{w%#?#@lfyGzDOBEy z;(nclvggY=3_J2fN*04qo%<`CJafT>d3L1xV#>j>brNs(VfGB0;KNLaJ!E%59u_a5fr@3-XhmtMGWGF}+CaIN9^6&`$k zV2duoQB4(F~daSDf-d&)P|6!VJY#k6ssD*WuLa(9v3`OwT(vmPn z<-W+661A*ic$Ir3<4p1||F4414n`YCw8>VRs^H)k+WhWnMGg*RTJY=a-`1p?tiTvw zncbUT0fMa&;k~0UCVPf7UWz+qe+5G+_I2N2VqOr$(T_nGkcmEz$3Hc?U$bHvx^@FZC#pN~Eo%pSuqGxrgD)WIYwPefKxp!0Lb;UdwuP6G+AfT<$#<-ABCKj|I6?2E79i*a+mC4Dpp zAh|17LA2n$u<>I}#V56rk$%lsZ^_-aKLD52P$#&;YXxBTc7~K@c=cY#wI#c4bwFKG&(R=m}Q&J$*|e)tgzn z0dgP&oyt&eR*T(@e(b*tq{AV#@mgYjHt%5h(h=7_1<*dx31h$yqh{~Hst2K{J*~49 zf8*rjeg<+H+~8o^^-~X2qU$^)%ZYg87oh(aB_U1Apny%-z_I4hhxI+nB^+kg)`bt-T+n>O zs9CgB8_Iv`JG90nBe$j)mX*#fv-4|~I{8H*8`!Ru20tLAZFba$+CRdv3m4Kq$L?ak z^HF~IN`ng$T(9og55^InvyGVF=)F7ArHCUs)`yxWv5oNEytUm!R+*oy*xpd}S4%<~ zwf>sY#>|k)`z9s&us3kIh_w$0_Tz0Hw{3~qX9Ye`*5FY^b?s^lbx>A?g&?ROMA`Yh zr>i@~mV|{8Ln09Cmt;5U4w8Y4$mZILL>lYTh<7f&ti4!TM|?8BRjw9b^NZR45>2EGI1j!8P)aVcS580XLOmcZ1p?b)nMW5$Oufm>gpmou>sFO>!Y%A~g0w}IsR_&(A!3;#@;D*id;S9c=bEm;!m4q) zR6ir%yc%7aFtOmRU-#|gi_vdv{+z$jaZKJ)9;KGM@>0W}1+K2t>-N2wDksAr z#H}~;IWT=x8Q$$Kc$72Pjma(Obs0k#3D^8;3Q>Y^SR#WAQ6NIVtBE&&xP^|2vlWp$ z(N(=778tk7siG8r$|7_ca89RCRAPfV$v)}W?p(WFX$UF^d2qcF*YqBlxiBD~{lKW7 zxC^bzb%1IDS`XW+6;2U#R7x^!(SO+W$-u}Bylw=L16X0G^K&6=IMb#AJ-3|61W8!2i{_jf;?9fIh1?9-v2eK{or=eqB2$x%&) z!LpO>{&?iFT5gg=GVo2`{2Oq0*XwBx&ShNuak4gfIZE%#GIX2a>ls)1Bf-O>B;`lg z1b24SiQhVR3C$gWx-bUAOUBgkEQyXN<$yM#W-E!WLC z4f-*ai}tVBAk>M}cbNQCq5V_9vY}0tjaFfPM7IF!5&e{B5EnDvce&E#0#tNZIK3X@ z9&9-2x~CayA$nvj#KDlzhgCYYR2>&EmBgqp$paQGFM&o;fO0RU$6-H}jbIP&Whs?% z1Uw8*KO1CEqbP>=r)j>n(6XQhZNL^Sy8$Ck{qV`g0;xA};tqw~7Pojny^@<&gGugZ zy9zF(=35J`8txI-s%l91I{z@|rC+dMdQ4{YNWfm>(ykUu96Bj8Yn%j8=(=USeU zdeK_B8bMnI1$LxI9c?E-wT)b|79k5-N??s+UOb<1(hx#3d5O2qSR2+7)L^k5eh80V zEjsNMfB3AXXoN)@ZMdaVyXKdWo&3q2X&AJ_B0|>g7+UB8QL`iIvAsd4lpxPvqT9+Z zd+jfRXd|&|Jb4JT&IQ!%WO7yHezkuez!g(O6MR=5SAKpx1}PI!H~Zk*;TOdU<^_)x zj-JAg7at8ZU(HZD5-hQw>10PKZ~D^BAjNbZjSjk!Mr;ngL!Ey`H0tA^PmkQO;&J1w z9<%rb&|EJNDpVjv2uq!)gW*ksWWjKQQRSsU`&&4zlA;xFGX8QI<;-V!1 z3=7@7-!1ou(CO!X#Mj-c!DC2uHP|KeRAB+Q|1y{}c`4uG*?6d+Ol1#e1F)X4SVgK% zp&)`?G9gIy97+Id0PE5~w$3_?)Z2BKT-aZomw{O%Mdp+GOj+tenk-ku3ZnbsP!RIg zTVUKYC&);}c>uc}VH}kGSz#x~YpBgTw#;if>5)Vo2UJ_zhg%9+WPBK2waRv!#?9r` zFbnBKU^<1CykMqMo*sHmg-8ovH>_+C4lHHG@s&)HfPo3ELoqqtl`Q~4R$~)sZ z?tkpX0wv4P0ZZjm`lEx}EXQozPYgTBeuKSt!ql9T&o=F+K27eU@M<6MiZPh4{E{1m zf7dSTjRliV4%L+3TIw7x#|>X7 zWpY^Pf6(7g0#BZBxZ;pRvox4zD@oEDB0gRc3y|*86m1ctHvH895$M2&O--iWbMMDk zJuOTvl%2m)*B4L+gBR?@jwx|A2%^;jV%MM!xY=yVwCu)&Z=o1+y*GOZ<3J{cPl>?q zWA+HKiibmjgX<#d$x2~pjiM9e7??7(Z83D&`2UX_1Tt_rfCGt zFOW4UTK&e>^}q|5)yTS9=E-f*Gm4^;?8(L0C@S-i%BYX8G*jey{-1CA`;7BA&Vadn zcpvoqbzU#-kKUAp#7De5vG##?XHVvwIw^Y=&&g+)5a_r$G*yIG=i{rpGLgQ0F=d-& zNQ|$o1y{R#)HLlcOx)eEp$27Ju`=uG!-i@Ya7Knhh37c)6+8>R$Vs%_PpOr==Ayde z>O;KG8C3XUX>b>*?A)E`D$ZQ{0;>K#y1U~?wQqybec>G#U7h;PIJpU-n%0*t((;9$ z>O}DMAiV6XiwJ_PS4FJtCY?F*U`e!*6y`|X-xOu*{<@j0Ac_!J?I>)(hFD4Op{_(Q znDeBm2aX%?a>l3Uj@Kc#)RfGsWsUtG2!`BpU+M66aan#VuM|&#->@UjgphX_`pUXQ z1N;7Z?O=zi`uJT#+Bmc-;ftMn=tt|N>Q7ito#s6RTyalre)}Pr>2-I?+xO2P(YHJH zRrC-isJw6JQ~l*v3&(mTa!|Lx?~Xr-s0Bb5$!PIUP#Rg@tat`#n$5nmtLs<~FTSSwQ<^we2%(ovIm|#?pb`Oxhzx%N*VI5_D$$?+& z#Y6WfSKN&Aa{9a8QF8dY98htNJPx;>-wl^8yJyIyrtyBna#z%F(!N5WF}cp9@K7kr z)p%u%t!;AChBGM3b!5%%0#K$jXF#(=PA_)n3#LCfu-$ZposG@(*tZ4&`~hcmmM(}E z(3RF@J`i$&Ud{97t;`hK!{^89!l&*ojq*oq$|N*?&P-#!BcFW;y| zV_n4D9-#DwmeyNGz;C<>4)2=tH;T6KZ-BSSc!XoJK+a{L`?jW^{dS`OcSoEI+S##l zY{bFma{0=$3WX#}11v<{G{DJ4ZS4(L?V;^S8cY!nh$j^)TH>2mOdAilZ0&T|Bh zjy((QOsP8kAV9DC6#^11=L7F9sND#J&O^&M9XtI}hp41EX5&Pu&}gP=fS!FGR}>dP z1S#)(S<>0~i^+DAAblx#xkZ2v6DsY9Kt&znrP!PNYB=@4&zQET&T~_aEe%!cQ@4aE%+)+Gu-mM03r8uRHY`J%=AdKb<))G68yS<;cc3A1NJz%IQrLw1w0#GZu zwieH5|BtY&UbalI%%vz2{D+Y;Oq0)+5t3&j#O)y7yH z!lG{Lf3fm5&f2Lznxk4=B18xI6^>yqyJTX^T-;kDh))&$GYi9|`@*lJdHBeshGa9{ zXIU=zG0nFny)hgcK}bakaILhJmvBc@%O4u&$EzGO4_6BL1Y*2jZ_j@>uLQ zY>3_R>dLmaYbH28oEj z7{N%n83jVWhPyPQD)wPeH$9X-N)baE_CE_eBYg)Z)E{EDA2$xox9|ANOR z=bq2v*4tK0I_z6>qm!CR^NfdtQhNeg0~m@d6xANySxQmFbKyl$-saenMRoeixap^@ zDQZ71I6M<13rd|7=wmRR#DP0S5h~r4pfV&oa|74wXxtTGKk%q%UJkPs_j^C{LtM|? z%OQwi;s8e&VqByu`GSeBk{Z#rj#s^ZR{{z_nAMj}oLm2_oD*`6b~;F#b8KTZ0x zoo697V-S#IVT$DBz_Us|GLP~%t8JmI9$S33Q+*W(V81y_g}i91y?2kWW)ng-VR--f z!{3E5D{oh0J!1<`doJvYhX=ec`Nw$?#>i+-eTQfpL3^RK1%{d{!`{~-Z!ru@HGQ!%rzZTboN%_C-aFP8z^PS(Nv3dxwUS@|fQ}RYD}v zVwbU**axZBt+bm1r5M7^J+sNB8ZQ+pqAoq}vd!QcqG%b{+;#6D_<7If&X50)&*M~n zpo=CdW=_ZXRu!H<~*%>Yt`a=s{Z*_}3uUZvn z{I1MPjjM_wq}VjQwJ~kyl~dA6I@UxchlI2LSQ14^c`bW6!x7&A7&{8C2*FV1ScTb zv0OAsi~4%iaG~);j%*Zr2tz9qCIV(Lg@eU7IRM+=JF&2M7a@WurtFE^#xj>v53YYS zDKVNzw-#N;E@j<;hHZW9bVF9l^#&@<=$IMW&kcnk=0nA**VEz{9-{YgY)!okBUW%> zrSQ;kcW~@>RqMz=fWEiy6*X`sqOfA;Q;!3(_%g=wCo-*(@EDfAN>JnhBRx@X_afP$ z>wEpbl2_D#4NL8~a%FsmiOX_3#GGncILy<+<`aTMr;lDiWX2lnweZb@!oRgN&+)>Q zl!&73S>_pw7mpG8a8lo?S`^ceTNNfmc-Nen=ayzS(5roA@~AwT*}nxcMVwNr?OJYDSTa~zbla>X{4t1cQhxER{Fv3m{CGKWZ@!*dp&f=0U=f`odM7kLOX8j#j=n+_;~6V z@wLukwViAgkM;Dxa?DJGd)t{Vze#)x0T6Zatp&U9VvA7QU*~re1*E_avNiVIOY7PK zrPokz*x_OFLyBsJUbYuus{o$J7C^WG>vwj4ki{r^;QF;?;BuIsPG&L1(sZ)rw}`NQ zL60_nmB0o=9C6x#c#9}{KP>m{pnVJn#cWxXBV_S+=p5T5xdpA7i4m6S0Z|N=5Jg%* zP&;Pnt5%38Pe2M4Vb?woxR&7$?&yb`RfI8D;ODvgY@neu_Rcf#l1`@Vou-`L8!$dDE}o_IiWAggDA8hk&q|h~C_<{nh-S?kDHF zylo8!qI%(~v5>^@B;o}-7iyk?E+evcCv19Z-NHhKh$0JAs`|r4Y3Ra)l~;JTfA-g| zgB-5XOxbrnMM_)8waJQ`s{C91`;TV^oWjNwYA|b;;f+oUdQWIhpwPuOQjmE(bxfm2wR*J%adplYZ0|pLP3xdq5(npQNo#5~}<2|Mq}*ghDtp(+CrP z9j13kKK1qI#V1Y8W3~UgjKVagsJdU?QDpA`Va<=`Dp1;)+k~68wv%ti_<81>Yg4v(bqxH*@K4yE&{sKiTTrc9&r2(5@Cf~hIL4m%ef-yKNY(E( z>F-F4j9)sN3V3g!PEX6rI>z%asb7AsM(aIOKen} z>nuu5b0o^)US^mGxlw0sH~jZ=_Z^`)?B-fFei|7!H}1;6BfoT^h_DxenYjI<0=o^_ z4ZEwau7{3!Zs^q>WN3v!3Dk+MebUpzx7YjiNOc64_IKr0hry#b1H55SEzuC_);nU* z6|WFY{~LJE=Z3Q$JU3m&qfWk6BHO&zdIJJFc5++&Gw=TZj8A91R9;irZx1YFr;!Py z+9Xz$BvIV-YP?~YM5YQt)nbGpln}%wvkh)bA@c?;J3nKN#(Lff5DWU44JieC=p zuqRAYnY^R+Z79Tv2W9H?%an@o|3}kz2eP^S|KHwL-CiwiRf*YBds8E3RgG4y4tumh zwY5sDh(ud$tw^ZatEHt{qp?R&MPf!3iM$(idaevyh%^ul?7P$qx-*<8@?}K2&jiInNfnAR(CKsYIt5z0iC)vYX40WClu*Xb zdlS-XJ|%F?{v@DL?@^Ri6e$1~b>FwKd~r>BbB38>?k2Tc7Q1Iv<=D2H!D{b8L%vR<@9=SM z1for{A}x9QDlHPVXv*Sa>C^aJ<-O$EGsRN*P7+)wq`cQFKj{kj0Kc=R^-?4?bx;ESs7}w@dYLBE0 zHKMmJZoAj1foDn19dDXClS5p47!%iJge)8VKuKT8srSxK-*q{n^|JQ9dPls+KIcTG zovrNVk>7Ab?1pxQib3f)uAZ9?fXS>_Pfz_ysaaNQAKX=5wMn=;+dkM2QjSRN6omXD zY9+xupPw=vAMQa_H_&$BN=dL~t$&M<2!8xK6U@=wW7AyJm>8;hv@Civ8*`upRBuCm z4sty56!6>&dLz(MBiOlZGm?VfD<%Pn#zB?|UI|lij)#fhD0X_QnBCNn0w7YfA1$Z9 z2sl?8)esi{-zDFRIYxW^7V|k!+TDJMUHdhltgv$(5hng$`{3$fR*3roV;k@!)DsZ% zUjtB43{wh}egVG^BHOL5l`Ye*AlE5Ew4ov7*#nXj<9EsZAlCmD)hnlg7S>`u@s zjW#KykNyI;@3vi)6wqrL6mzlFjD4**B0cmtg+MR2W50l=fGM+&JW~ddU0=S1FN@3y zj$OTOp*6f1pI(o@TJ2Z7br_a`>Q;vY2quVtMqZ&fu0mtZqJ%*sks58-9U5*wIeukU z|L_B(dmRns3SAVOB0|5%;D~nDXyeJWQfL8lLBN$SmF$&|a|idW&<%ELF+R1iyGWc< z42Tl4Jl*JAS#Q+4k#5{HXhq};I|UB=Huh9}_+dx$7c<@H+0H_>#LUbT6JRO?9Mn;(IS%s?jdCnSm8IAnrc`r&B z)nHn>rhly>Vv(BoF152^YHQ0s6H%QHe?Z3nh4~P3E3synz^OxI@R(53pmY3+)r)x7 z<(pa0D}}w&6~or%3MIqVil71z&sE+V;cWpaYtrQ0S|T)CI>6E=6C6FYQtK-lJw^}9 zYWzF)QcWK9V{rCU+dY{UhT;zMjT;bN7*JRy_mk~y?MPfUwZ>RUm5JKpfA(0kGa%FB zc_%uzr(GsJonIN6NEHz^sqIn7$oJ%<@Jw&e!%JPk89(@_BtmTme96eqT}O%C(O~og zP|vSsYIi2{{eIG@3#xl$hQbYORnmCmnQjOz4rk|Saep0w{gKwAFi*qY-(oVm0QeUN z5Bz*X<@$?Nz5VeN*#E4#=huK44?`Hy826tqI8!}*7Lva>a+EDiKB$@Z;VXl_sNlk9 zeV*A1{vYyV(Eaf;`q$ulR~br2<%wL~Bl&c%AKRBURE`silX$0BiWAlv)^f+#F+qhL zPM#6_&A~taJ@V=ledsOB(^5%Q1l5X6eL;5y)%jQmNnjaS5KJl@l>8~g8M1tC^geNj zr0oz*pmOtDvSShgK-cl~leW&;W%ZO?)8KNpsK*Mq(A@?7|l56r6c3!pWl(O_o((MUX^~b+^ z;f#QBt)p~%)Ci84U4e9NoD42H=xS^2Q5qiCo#z1~uM#?gA8xGdUfI7@U?0Uuy*6~; zPvuQvU-pg4s?6fqCxIJ}Br=v(1#j*7$>(G%-s?4*y;;H;!QdWKewM!el-pZyn^)d< z>ic7=?{wG&awtd~QtvJ^_(vp&Cp}-LjxgNwEcD{Jt3xB`z{_A_^HY0Y!o3F1{9_+d z=j~v^o{?On%sOUQ&Tf6kE9maM(EILkjpq~Bz zyvJ&{RSaqy<3Eh97-aF?YBrwtr`afox!-x`dNTQPBSqR@cbAggdz&n$J5#pPb zAbY&W#B66NCBNz*8AIZ@3?@P2#y>#6z+`M_Asx7flza)e zbH~9KO$;@@(SJ>IbI{gr@L&JPTIKdZl%klsX^|X6)EpmSIr~M?h3tF>?b?B$)xrwr zJ87FDkmD>d9ph>`VOM@R$lJm0k{jjDOp0>7+RRh#)t;FOCw1cacN@GHFv|)sY>9otY%u4E=;#tymPk>6W>g@inw@ zP|up%)@noRS{CN+)?Np4SoY@5-u2BRIPx#&cj6FkWiHRRRo#P$xE(g}-w(eOhx2KQ zgO9$NiIR1T5&U7yE75^do2~2UM)`6F6Jiekgowx{AcVGg>%AT|*KuWMk7Em7E?AE~ zWP4?Qspo$y7as>}F1&b^s$}5%+S`08&y*@T3BFL3#kWbSQ7aB-u0Pzjkh{rMWFh+b zjq_u!L8z`f;?Iu%dWMJq zJg&lUf3v8*CksmKI&@pncHaSI`&8Ib*v1}sB7z5|N1oCPhadFnKd*C0>&K?`dxXT= zm-lG!S}=}8z3h59s(Bp7p0B(QyC=0Ltm+)B6c{t$dRL)8nE$~DW$Vb#Q0JN`q#o*| zWOY(O1z`tXX8jY;YTllJbuARstG7S0aWE}>R?+Y^k2-toR?^c#WRVhhq?luG-(do* z@Q-^qzcf{G2jQzye6am3t5Sz%qh!UAeW$2V4sX~(%CPe}_L+D3`#t>cqqKQZbD@QF z2Ncy4Y(;`B*SReFT!eYrAA88{^@9F=@-(&kk>@cMPRjCrNw0hhxrs+Q=onS29V%6E zn9GxX(Z1|?Cd7?MkkY$f)?3mtIMZ(P|faP zx`^`mcT94EKL=eJAm*~9_Rf_}a6h`18on>qLPVf+Be8W#m~9nI>bX#3zr8F8UAYM< z$2c3IaCYND_n(qgB6wZtDNVM57z%^m`L0I=!e~JbY$qf{#dP67d`(??FLbfi{7fRjuv0%bfT}9%dWb!0UyQu0s^u@XP%xn0@Fb z;!ngio}1#IpFO+tI$!%@fI4cbKV5Oql1@~1&09vbM=F6MaZzHQ8KM+x;DjCC1pfQu zeA~pvK&O+8+5Hp>WDnuC#;;mHFMNh?gKQZ|F0mU3pcLf*Xyb#ua{oK8!TSiY1G{Qi z%j19W>t;<{IfCvJk-jN2eojAn_AFR~S`LIhdah}O;e&R7gH8f(v4&Z0s9mDi45gRl zfutFEC{WqLNZCci{)sbAZRVno4|LM*H+~EyvtlE zqeGNN>k7M)67LE*sqw4k_@r#b{V(a2-?I*YFCP%m@nu-5 zQQxJwo1e8pRJp|=N~2>pVXEJL{mW`51vR*2MWOus=e6!;eCN8MXM}VW)Shw&-K>4v zrz7G^)g^IAXHUxbJ{PlEqL?SV>UP*|{Js*!x%cH_tFJko({COkbl;^DSke?en?I7l z%RS3qOVCL}xe0pkDy*#8`fev>c(jYZ$GUo+;i>zqwS(G$ThwOI{&zjY$n6`J&km|` z6*R#oy~L`u44haj-O>Ka)&!>XfW!Jyn8u;qkwxV4nap;Zd2HT^zC)xuo)}qV+Zy&T z113YW=}Sq)QinH+yCA8Aw9|JPj7&drK^tJw|4qWhZHUS5q9g0NgD*TI;`nOzbRhjP zIU(Mtz4MYsGXeFGS6mr0kRJyRPNhQ4P3EzOv)B{$^syE@mZb<$QWt-`>f6;1W%FHb zF62y9idSKc-b10TQDDLw7+jK^eXs2*6cG06& z&e%yAPgioHblEjcNz7!&kD|Sd^#`=XcU@deuTrnZugTh!@L2Bb?S(o<)HyElQ|+gz zB7fMT6R?L0hG8|j0yDW6iFAb@&CJ9)eUxUTN~vdVmeOJL^@}ci!W`eyxeJ576yGnD z)#88N84taR9SZ1buss=5CqUdc*py&2emdDGwJ~zgZgT{ZwoSLlw$PDYNzjp4Ib+(H ze{+8IO-BphEn;t_Y7Ab@4@Nv+1k78*?>FQs8k13{9vV!I1Wl}OHbE$&=Qnz{ zv+d@s;>TV5iETcp#NEUfOH*ePQDb?2l4S;bF3R&6ZciNMapx&-pz>^HnlUt0h%=Y7 zeFC&;<5dbG&6bo=|c+*8kQdh)%HH7Fgcc;|#kkwdbOFx9E(sc-7Y+ z9cbv?fTvosVA8n6OeC#&iWdj~+KMG_5x)ji7vD{HL7453)pXOPlea*PYA!mO7qb(F zKe5hn7#oS|P|umHojrPkligFklFcC9S(;~|KfD*wl@6gu7sEc#O>0s1qxR2yWlQ=$ zb}T3C4eq!WmcTs2_dlhtT4=xKS}nh^&ZXk}eov=F zLEnwcD@e17%7M=4L@=e~ooSI(7op2$+&L9icv*{!k5=W`W#bfXikEV^|J}BIki;(y zEi5!JufQK<#wP%Gv|P@Xq(R+OiaV@Aiw}}NQ02bGCbZk!Hm^v5Pl$aWJQ>g;?>v~1 zDZxC1bOI@>28c?vX|K(EWdWKH3@Ds=T-5cr02*s+yQ5M5tb)dSy`k0V3W#)yUW!(>>YF6^uzF0dSBOEA!;+DA=D!@38V(Xva!e-77^e-+U8 z^#V3Rvu9$WRNjv0JE^Ty4C;TQgsv+EW{xBhvDK$LeZD!|!`Ws{SntdiE@J;6p5*&P zMTky=3S<+*U{2JgW0E)}rFVCTxAm5nlve?RT`ueXP#l_%V@4Xa%VSfCh z*!}qP%U{#EN2PBHxZE{Fx2H$Wh)`^ZuL2lfQG^^|Edqf3#g`Kr89R~eL~2_jgOpx! zyWZTCg7rpORyn`MN-n;<7tJb)Ncd|Ih ze^^8cJAt_Q&(?8%Y>#?q4SMN*{@sXzgQtPPh_XIN!cWoyd-E+QEs^+o`yuU3v!5pQvy7?4vSnnr6s}P|(>$H1GTRYA8^y zrGsuBW`-Ud*}*ddb~2cm6+1)jnSq7*`R;|&mtZfd>6;8sy5+F{FU_Z#4?SmV(q?@R z@zjMfzWrxml1V@0Z5-y*5*h^qfAUuIy?b=Nvf22P0j^*cAMsPQ(u?Z}r!%YJ;`bDN zIT9cJGU-AqWPLXWS2-(~fGfH+!cs}!#`ehfEG)u!w6emsotA&|1OU1k0-9?8vtV)H z)rX!T4iz2gYYv?z`o5xkRs|glWtN!Q(rSgK_(;T6z;FyHa7= zJHu3Y-I9S>hoQ_!`AM>D^|q*B<#mC&wlBlqHOvXM&}9Suk=OQUNX#*+R1=}`9KlX_ z_k#Mpyg>&*v1yd%)ftWp)t&PPr0kN=0r}=eMPX6Slr7?n6!3NYD$6qYz-~DNKbb4P^ z5d(=qSXx(=6|HgP_5`px#l9rKl?2k0e7k7(OTsZU3S)d<;L+jXMb@a|*!rSd^rDxt zqB?hQ1(Q0y{27)xuvm{X)PT2D7MI67^-vM>Q$?`lDxx2%0H`F>3JKp&D%?2~RwQ5x zgb2?Gzf^M9;4{VVCyX3U?9c2CTjtD7z2|GZ*HKv^gP2Tl@gyi36$UL2S=ks|BFGV} z33tiUcV>IVh7IgTj>(uoQ$9aV2;L^-A^7_WcnGBU2ne;^gAjP1-T!X3fA502>e;ER zn*VWA2;lyh0DL_QWxQfiF%ptan8n`m9#Zu!>?Jie0h=Y5SA;(tYQU6Egk+iY44Ek$ z{k0Ice8N%Toyq+E0}P~h9IDNUTIu>?R@D;ftcT%;JB-NlHO>4WYV8;~mb3NXvbJh6 z`k37xFeCA3({zYp;6Sf$3vDiA!Nym90cE!G&BmrjY2pNxbVa32H>^{>#VRNRVHH2#c5_(7E1MR z4h1N1qDy_}J>`Q}Ty573?`T=(c!k@}YCP#L;T`*T0wwY`J<2HvCgTEoc-3#Fqf~wv z#Qln}N(=TBEZGCF>goF)hi`GKS)7pAwJ@r{$)qO1b>$3C8P6*r^0_SOcMh)i_Jpb^ zOZNN)(F_qM@d+fiAX}*tQGN%-N;w3ps+b+NuK=lMw@-oF?54)f5sjOI)mGI;gLU`z zS(DrVk8seiRRtw_Yovb5%e}>Gf2Y+FL!t<0<4n}QD!xdgFB|qw;Hz>xi}2 zawUu1YplqBk=f-RdQ!k>(^Xpy(wP19Ki#@4NTGH3f4F#mD1RL%F8|=-XUHNC@AcaH z_;H<6$gmfu|D(N(9SAO-+SN{We)-8AxkV`fNuH$|ipPyKAMPDvPf1b{BRK>Ejp|3KAfNL~grb$Gg`4Zr%UN zCktCv4lMiBw5#zkQb%>Ovo)A~q}qW03M{RZaHItzCf?VzuJ!g8#u+;Oy}{^U&W8Vf z9WV)2uDrp~9h)6~^@VooN~_9`deJoJe;or?K2<*%u6Tyc>V{mvsQ8W8s2bKq7Dv!v zhwYs3wO?y8VP;uq(|Smje2=AOr^%QEKvXzc^6XvHT2fW=Q}7bX{3R8XneHiH%;8`E z5u2&A)DklD?sbpkNfxHptJSm^hAbJVph3PP4o{TefP)ps<3WpqhE5UfPxnI#$BHBv z4MF@vXXYcW@Q;|v)jcvOPzyRDoA8S*r7fT#(b!C$ph7hv$wIN{wG#v>26h>mQYYqV z+I|e1SF9YOC^&hE?N^PaqfM8R4^0yx#J5?=7hVYBgtQtrvwrEgs8?1kr*~n8%D?wY zV~Km+$QG=T*6EF48Mut1xxJJ9Qf_81JqlWnKxX@Pb*~E@w%7QD5EKcocnDg_StSCG zR(<5Hekm*r3WzSH1cW^HFD`fNwh5dP`KjpWwRLGpriCZ z1|`LE=m&H6LJJ{=W6@7_IDcv8G9$_MPGPctmz2nm3#H~FE7?5PCLl*a+gU=8Zm9Or zEN#}%DL=1-aQP4AR{2rGpFQ96c9SaQIDu(eW=#X)w4K*N?^y-2H$+<>e}{{@@^`|T zCMIpYG2@i4BL;A?)d)p;U8*aBQ-Oq+?9e+jJHUmTYR(_bRs?F&?qpJak8Zd;(<4tG zzJk6d>m>K~S2=k=$r1vd{Q2dih( zaN8gp@2lqP+ed_B_FIB|pJR;f^gx1E%bJX{DIw3Tc&lzY>ILGi?&v?o&6{apQfkfR z-&&*zo+4$m6|AuJ)3=#(=kVkc1}Ij$z?l6=OSOiweeq$s@3|eB?cDYAiNG5$)#pQc zZPa*c+{nlp_MM&gYvN1xY$UEN;`S?G%IWdQ)KJd=_Mb7n@f0cP53>ab8heg((QT}O zcfZ#$(=$Xpn=l~?>kgB~{nR_)VBKYA9p~H6A~UT)1ou*v+hqj2s%e5|!d<2Atln!C zw?|T!pW%mjsrRUV%LTmsC-0Axl&}l){B*h0d-GL0DXRxBjPzovCs{WVB3Zak8GOpV zb?Ja9MmZxMJk%vTj z!QNAVkZ;HKR2sUUm2)EWysSZ|#Yr!TXd7qDvCd2*Ka64TuJidOpdvg&GIW=S&vtc(h4F*?I*G>^Hoga@j>`Q50%x zs|IWa>>f8sWN_*+o@qr&1SOG2TzQsCd9M&9-~KU}}%CDhQ)AR&H6 z2nJ=d0BSB3m;YGJU;d;{mvbrMql-~A;~R2~PkT{&<(Eq7t6-m3-x1YJ2Kai#e zD9iH9iEaTSyd}XEpRwGo|HG9Cp~Ry=_PQS+vXGFn*NTpKt&;cHYSuOVhOW1)?oAG( zVY|HhAw@wy2Of{^)5lyr@jOuUnMzb5WHDGk4^5Gd8V8M^l9SvpX$xeLe}SN*n?9E7DWs!hDU3pXZmyMzFZJANI_O!0 zy^K5u%Aog^?7nSQ%NOqU;D)nnpZUn|>+DDp0i2tuzPIC7;`Rc*ARrqH+zlUaWY~K) zc|)fo@_|wDbD%;2ETY>3EF|WOTSX~0y!O%=VGmA%iRcTK*=}$Hvz1y+ zOts#zRw_Nq5>}abb^z)1%&75&M+$|ZaO7JQ_F$p96lE!#OzRo6FFqMfM`0KFvQpCX z;w4~{Y&n1WOl`^AqOx5Pu(cQ@bE+?JZAD?{ulgP_V25+0zkH(CogDGVST!5jLOgkw7-}YsDas0-yiD^P4!u=$u|w!@<6o% z5yv+hn7U^+utUTjbx}H4j*BrM9j|R9KmO35C&HqbU{})WkT4fgC|fQUuzv}qtxt7( zYDofGN^V2ynw8lL&oi3=s`AZP84zf2^ zJs6TcZ5pb~02%c&nEKDFCzPu=YO+1f)>!uL&)CRf%(Ivb2i!01_$NqPyR3(;2_ zKexSwpPQ?&zG`dj8`dqiHlLHtm_P-T(4?#P&-qQXGB%Fus0osUQrqxZtw2rQ8>8(rh2Ku5qDSo<38PlX&BUeXO#rqQrrRY^1-u=ydcjS1=1+d@M zD9wJf`iayM2JC@Zmg<>89)7iVa=&kRvSegFH(QsRr0R&*IcLo`?=Z?*$7PN$X2-jF zsQqDP+Cj3J0w$?o6gp`zaCS>GKGgGTe^-hFiwCw!bG}N1AE0rVU0NoL7Di}!cYkLL zO)vtH*%dkK1nFuDjdb_r!JVy)xKudArW?WRby10~N^Gy=xF6)21%{G9 zdvqjj{=6UicGj}8gVtblHrE&p5ze*`$Bk3hA_*II+)pDm*Bl)(jOv(sHieF}&kW+R zkQ{q?-lu2VWAC;n6oN@4=?U?Zwek#y7?;r^YiRtcNiv``_3^d-kmb2c8SrsE*G$hV z9)E5`%{9Ejk@r1p3`d}X;qo9_M((k-u73gQ^p8EyOxP3jli47m;`4=^q*G*i>7)7t zd5~`*sIuL9UHO*uwBN!X3YXHH2_3;~Yv`a2CE1EHlqz^^sj~wNMS19Wu5b0R(+}Fy z$`3_c7&F9i3lTg3#Af!1T1UcxZHcH+rGN;8U=cK$y)w7U_``JQPL{!&1l|lF+K_Jg z7VbPU_eRb24buDNF>i%^gpLIJt$)Wv`TX)|KqX+ul`qdI+B2^M>RrVfrxUOsTUw7* z%++|IJI&22kpXN9YcCe1HtSsj~R-W)c8{AMBZ=CO>^$RW$kOI;De@ zAqvS<+=1?LMuI99`SJ`rb6U8=+)0I{NjRdA!NViMrj_xwidx^4Pp2?j$}@-j&N zuoJaHEXw(j1MTn2o`9&FqVCQfDSm|%F12DV)S}YmgN}ITl4XezKkntlCR>Fkx2gfMd{RU)WO&9m4#3s za==}0ocE74+_Q6i+Viw`UKA7U{l)Pr9E`}hz75%u*a-C&KAxiib!e9R=$L3qMS7IB z>N}J(I!8`GOy`YZ{8>rHqL2YlxoYos_^f8a{@?{S6)QW7E2ihFia?)NKkuxrS)gc_ z+^D4-oC;;~nV#>N5qpnabnn{uT9Hw?Njphn+zGwt^YKKvQ0hbsFCbOPxC8%D4W`_F zxA$i)Z-~8H+^TXrjkE;=;N!5SEfF-HFiH=RG)7Y7%Y68F8$ga1mE*D|;yU=2Q17+H#zi;vy z5N_VrsIS%!p^+px$QbnSbf5EAx( z&@Occ?RTqlqsVuby7zf0(7FDe&RXV>0mr-TZyIx;-F@jG|I2eBo>Jx_q0VWEsDO9t z$&Z%>Ne8*O?jD6ww5gjE;9m;n$BPN7pMrd^0OJ(eZcoBKi7p;R{@ZZCh@vE5C7~`* zW^|xZpj%!V26?XG@D0%Uu7x19T*bs`XM$}+O_jUsp{`U8d+PBT#0%vBkb(0{F4@@K z@L*$cV3dv|T^=@-HU8u|GFDlxuMmC8AkG-|HOlg?R5Wj-O=Ql8N|(5nl&8N_b}#nE zrR=`mkWEW@y8C1{8~{3oUTi!se2ARWntkD(G}gWvnAWY_o_z$(g3piFLBnVn(0uoI zf!_z7TZep5_wU46PdsTHSy1M3G@MBIasjQ9pz&*B*KTJh=JbMY{NVL`p%_Y)9k=|` z3iO7x(@Ovd#_AlRv~%%$yN!=e6nC&WdgH^)!rD3j6Lz9KNy93`R_dNvwmV1Cc6_{U zx^v04CSR>5f}CwDK^&JJYis|^;ffX?_SO;R9v}5)n5nYQkaHM7m&Fz+cMpPbJEoZ? zs{x{6;0Aty8=HX_YI(eF@%^U8*L1h)zT?Pgt1~s6yAh@$>&n&QywHtTNBcxIiX^|cnWJO&MJZ|Rm{%s`^H@bM3(65 zi&n8tIQo^k+3UVu=0wE0x$6NdF%rL@xKk=>J5w<=x~5CPSD`XXeg42B(kN!u{GC;DC6cE-bK_C3ivxZu z@3k5YZ_N$6yXHuxDN5(>7F{q~~2ih=eEZI+bt8s{SEd*_JLPpRg6}8*Peh9=egPos}@% z`@idv^B*d1b$`F+QR$&(r864wo(p{Dv{z69<%!Pzz^YDIci3U9ps-W?G2mwQOLiZ| z`4?H_MkdPCDt}WnFGNT1Kye3J8{~E1R|y?vJ5NG%RLQ`S$borTV2(puo6x~8 z?S3M7Z(n-<3WEp^bMN-^^aK(JpDP+>NX|X57gC4Rem_Be1TZla^HM{W3-Jh zn_HQ zt~$uRQ9LR->;YC!s$9UApqGjdBiPrqbZI?UB|?Ybg|u=8eR9cUfjtDN2BMk>K)vqD zlIeqiD~YT70`Jl|Cwh2(I{M7;Ds%a+SU(t9o>+@OIYy3mMri?)6p7<_roKeig)!^9)5E$ZZYdwx02f$s}C%&6qy6p$Q#TKXjGyH#BqY8r90wH=MP}q zny}%ZU>jJhrPX)SqmI&#TdYp1^*EVZU)fT(F(A>vn73<{jtQKs9C+C3m_N7g4z0C& zQ;l;ZU#Jzd8#0=(yOtd;vGm0Y#?I2%6x>f*D5>kw=ilYr-Ci(n@xoah+TWubc;@L+ zN@~7AsP9)4%P)+*oHdBe)ix+D!eksO*g5-o-;aq`G4Saa&h4@fGmO#7qgWEjDF)5sqb-2|*Kq3TEtO%&`T7X<%+q2bal;6ZA2_ z(baZ`RIm)71U@57<7JBU=eHnj9?zFmMRo7H-L*<220K+zgpSsCRg1TbQu;3_LIwd7gsYS+|wKwyhS^h@mc3tyQymw zleQO!a+>KqY?N3|8z8~vZjG%w45~jq_b6uAcwFW#5GEgV(aA3^;SQq2mVTCO! z?qI7xrR4wplduRE;5Cqj5|5%46_>2~08-uJ6gDosvu>f0n<;%ve0k*l&9U(W#Q76V zUE`($CIJt&nzsQzOcGn7t2@-U;j2FCUIS8dvA^ATVU3JHZpbYA&V~c9WnvosB`Rxa ze@PR7MGI_JebOMb&WBC}68FS&3gF`tmN>5Zgzi0i0J#=)Cog%M{-_GOFcTP<(5MUC zi^*HXyB_;{P=z)q{t(9c58v6!3Kmm9sH|< zqag?L18FUg<{qluT&+kBc6840$vC=8(&OP%({@M8gT7t6t#^Ma8<)G}S9x!ae6qR! zwXWF0N=*b)kYm>2w?5jP>s(zyf`n$C6f%m4%>D&H+7##01|D?>L!PZQlSK$=0|wSp znlYqlzsm2s?i&GZ4fBc1G7{dS9|8y&6-Iy!mOB}0mleH}Qe!u0T!#+L>&$sXh6`QQ z;WNjZ3E&T$;<{E0kaQzFfKzRO7|izvZ!}k3B%K z?#p+;M($?w90EqXl(A@vcWF#6^A0KQdn39_DUELRso_G($*AowXc%T*<=OMdj1j|l{(3GJH6r1rpWETm zG>MJD>bx%uY|c6?UQK0N-Acj04j#{fB_I{-HQf-Nh@5O1umphs+i)gqkniuY4GNVg z>PMX11u8Pal3w)*MF$k0M-2IuD2Obtu{BqYB=vpy&)r{;drp4>C2Y#P_yZ($7(7?< zJ-^e$*N;7ef8iGW5$2-vhvVoGQdo+XfD#*H>+|p)@iUlB<&uX6l>+&=!+pI=;F0G} zqPAs@b-v}fS*N9&9+mfeF7d6-<{Uu->7scUbT``=zd7+vNV;hKoWNRtL8t}_65K()Xz$- z$O<#ZI}9Nr-^%E$lO0E4b6%br8OMS7mg{h8ek#T*AC1V+-eWY|5;Uk*P+S+bRBbsc zpP`P@ezSH5Uy9y-*YhDn*GRylc`$q{FxLEdXY>Bw`4MIu%>yTRG&`V&HxI(@ib!<= z%a8Oi%!dI10%44W>#{|^U3pP+gRsm;w(Yl zrA|QSQ}wWwg*G5@Fy`~4dh$t-Ex9{l5!m<{@a zUE5kLSoZ)23U89XbU~_S?P~Ot2i{OSEXt3JE&KY1uXaFexCSr9ri%z#_=D5DpY7fV zpAfDZACMU5P9^MT6IMx7c6*W9gYd7qz)7v|YMRu3Rz-wITnZD;6K*Il9s!PC@+cVl zbG<53wA!Auu^;h@5Ky=DB6;v)ywdLo)f~py1vg>J;rFarp^#0QR9G5pIcZjLwATHM zVUCv}Ru*}+k`*Jle>nZM}ieU8#-dXehW z@aP%KEQ?d4Ae8aYWFn2jYgW*Kg>suB<0n3o5@|g2dmc#)LuEq8jih&nrleLWGl=DBNLOZ@dx(2X6 z(Y=Oy<`+x|DIWYHNt3ApP_1vO!MC)eUa+j6<6#?AHljmu=7?Z9bXkrpQuGhD)okiv z`*ZL+bJ5u|OXg=bTTTA2b-nUV`NQZ$DtAVXSqn#pE@tz#0SlTtLE?5mPO+@Yiy<=}4=R#KPAXwr-%;z%T}IAt~3thGdY3oVXo~jwFCG_Fdiw+710fa{o4j zX^Z^dwNBp<@l0{z(Pf}$EOzdjU}NvlIAZPHI7h3*46dXTVW?h~OzL}}I z{RfLdbYSx#%%Co~;Sl5AFJ!P_Gic|Pw#cB!>DjlL7lup>M~WjGtv|=syRBkMM)j}! zP2{b*P*dz%a!Kp*npZBdR)8m&V46u7?TOcZp+hf_P=4oMc!b6Z{f198m_@VC!{1DR=C13J{TXY%FxxSoTOw@9f@_QmB9cOTg}&WN{;c>Cl|<3_QJ z1f8Rc>I9xY*drlA+e7uhTg&G=nGF{kKXPuk+^XXAbypCcyGRijUjNJb6@`@|jaRrT z_O`QSjV^?eu^h$>zcQit&VQMtF&}C;%Ye)mh_uO;L}MRW`N~O*NH|C9bb{aA z@2daL9M=y7PtFXDy;Mw8u+k4J-qsP{OQIs2qLl*`FE(awp=d@1KqF4wwFx zKHAebIr$v?gv@W-cV9=srbnL6xUpiI;if8k;L!(36I4kq_~B}KPUMa28}&gVzn(0h~Jk&}!$vl{|mIVYkP0)?R~ zT81#k6MJ3Y*tWI)|4h&_BI@rYRO|xM38NU8MTKp=oCK>y9gmY2iAoF^tZp#%`XI#B z)vGww6T*0?T3(TB7HU$REdqAEaXx)eZCElv_Z3{|hh8`Iwm6ny{(H`baU=w z^-wqv4tkFPqS~>sRXh1|DUbdhzN353X%0EVb4uivWMr@>8k1CO8o|JSo}tMX7SaiA?vr+3j|>{N$B26%T>1!!&F?dw6r z8sDx1`1s?(QYTvejE+pUw5IU?erh|M!I;HL9vfo?3q%%QZ{1+-f-wYa_;&a=R=6Dg zRQy`PAHY4~15WLl^~5W!!IyCK8sZPNAIURVCyi|^2jk^#mY;f-@^MGb9a<(2HMXj} z(`c-kgbpdcMnKko3`*{LztbQKFSSgZLHZaD!Mg_So72+&QTG@%Z1D*F3)2c8`3e{M zk~Q6ZcS^ruCC6ItZ={;qYLgVFYo{krb!^1$qVarAM0 z41XVUwoCGYMGJV;!(HP?s6jcKrT!5CvocV;vujU4T|~nc~{ov|4-h4Z188y?3o3=yEPUuQ=FOJZF%3s z>;KEV>^Cf7@`!(?{&|eb_4M56-{W)Az%TQRqQNf+ROSDGze6r+G=1LO8}Px5S6nGV zJ3()FP~U*gnS}ivGX+|*O0x`?L&+4?ojw(d6iJmX)sq;8#TTrD<79`bKd7w&)lX*S-S21OC}yN{$5viVUHkuxjt0w3znBWd zsyp*sYGV%wb9bXPp7o%F^v3eEdknmg8Lyi0)Z9y0bypC<`PTFj5s=VsSX71?oS3f3 zi(Fw^zt<+)H7i;I{f0h8p|pT^MzIZ&L=*L|atAoxeNL6zLxhuxzZQnqm?Jd6>U4~V5C3(-ueN^GOok94 z=5Mfw&-9j`ZTj=G*H33Ze087G=<5Azy!gMa&Z?wCVlF*>e~Rr^$Mt(>**NVk+g}z| zX%FUDG!eXZ=X}vSlW)hH=|NtG;Qooc@gj#eFpRKuwP@5ZE38fzDZ>`45wF7z0n6L! z)PW?xp<5VO$?Ub}=1#JPi%}nel;chs_VxO$bHmy>)~^k#2s{E>UXNDi^S5WFALs5x z^L*+*p=(^0J@htXH?E%)_KZ%U9TehdN!!C~=}jR|dfh$R=^FFxfQO4oSg1dxQLN+} zCcsYe8cf{=L*J`->y(XO?eQWwr44+i-;vBXO{OU;?f5zeS(pQje9Uk0^o_En%1iLJ z6;ZZvOKR3B}Qy@S9$!qjsnGDq!~O#tV4krlaH4)YYz+oTIQUF|X-we2nfV zq9fS$cN!;m_@>ovZFjAqTvutZRhXr9n|6CS*Qd0c{-2nEI5%cKj2zOWO)|8<*A}HI zjJldmhI^gWa66acxU6U)lrsEten#%_v0fGVNVgnzWOZ%^XOxbyRK)1zK6lqkjeks7 ze!3t2rj^Zgg1_;K&SY=~FjuJuDd^vCyxX z^WsI}OY?BVvBU4DJK0_)X%e?TCM$)?ELR&2$=c##@VXnv=`jph6m)S0?73;LSgPGg ze!6VAV^OnU5f!`ts!jFlg9y6TZGlk%c*)AvW1t6FVPlhDP2z>0vW{ztvWW+2litwv z(Oa-eQDVBF4u^h>CR5`_8LFbTZIa*1unmfV{KSG`w3^1!jRzTbU0Nx8kj=>5GtJB} zOmf=0nYt_c=^eNiPRa-l7MDReMVh5<&w1BxAI1!63Y{r>!iubJauAEV%`1G#BSE-K}%wZ^S6zj1_{EXB!S-mm90WI@g)Ih3KX;A zfQhsXh3tJT?j(2B+}>Q!e@xheVQReYx@G_lES=91D(s4a2y)?&5};j`j~)SdvIP-F zZRulsU!za(C!nUfNp+v@PS7pf_Wpl>oUUC{x25y!ef=Zm!HUcDZ@Nxc<}}yM--dF~ z8ltqUb@#@hy+r?eE;;d~Vv?fkD*#H#=fRt&BqIvdA(}t~<%A2U0zhui0e;B83^evp zavyQjAPu~+1FYDyKw~!;yj?{qy~Nt#uSGD`j}<@X*QXaaDu%S6y-ITLl?bCC7kzxr z$NAYq)LhZ1JCO^ZdNA8Y(b{$oyOrd2l&IdNMPs6{q1JwCiri4hgfLz$);qlJo^rM} z2@+KHQNX3UzT|1HdWI}aA=tXG8-E(3$c$HuI}CvHKq|uPAC!#t9(r!!KU5VrlVQM< zu|VGBJ_A~-y+`ctVvOiTco)yf2o>QQwQVh58l=WPXA8RL{Py$QSs##lsr-ijy(&}P zhuumo=Jz}<6dDMQN?oY4UrgU0L0*rCA6Z&t#46B&OftP)SG~KRBw!eeJg|Eue30Ho zc>FIwtL=^a+^k>VzfJ#D+$(2W#Js(n+w;t~BvG*o6gJ2h-s}&$OLI-14U*XV6NP+u;h{K|I^}Sg| zN!PGE$H33bR!#v}LP}ajYkp0Rg3lJic>Y|(%ud+*lS>2Wh_*6kVCDI`0XYG}gmXT> zIx(^8v#Yt+7WfW}L}BH{qA=eDnSZSphl!eX18x;sHMkf7M}dI{ezO+KV*1i@7KA)5 zelfz^WF>-0W?Xl-Ub_^au7=&AdzC2^gABn4=2k62_=rT75#Czhaz&&ZwkuWR33Pj| z+6J>Evw~0&V(&E(2A=(HSO`LG#?#g!T(JrluXal|=f%9o?|13E>7FcaWhAF&YmDw- zHcb>5_XT%^!oo*bQWL1xtkr)?JShGI_l4r(Jr^&tkLC2{wH-#;xvpX$VNz;7F@w~O z^*Y`98=e_N*$I?WQ0y2N&U59TlHWwx|G1MtuzFF28;AkjHZ^3Xn`Jmi(b{{vOgCS0 zEC+4D9jg#(x7fp2S1@W=-ai;rYFSaWooop}HpU?%7(}oxFT_!hFl?KyI_cv@G6;HS z3JG%4<;2CB^T4-5Orw@s6}*$UnxLKJUts#dYU!FhY1oeua3W;G2XYR~4rJJ}=mI&B z<)Um8gmrz||HSZ2NowH0fk1Wz>hyycV@E`HLi+LgiCBa^`vMyJp~o`_>+&1e-z!Wi zncMRg1p!Pgv2D4+?Y1tTiEZKnf4>+!06OsZ1fXv3kaJR8d~>(BRN#e6=_46^b6^~Z z%~LwvdUVt@W3`p6c;cw$eCi30OJwOp>J6?d$0FeG>-gHg`?n@9!OpaUTy7nIP&gqx z)k0=!K0ShLy^`y0^2`8!fwzoLO!Z#&OCz2mz%KE9O$!B&OP+Mc{m{WN(h3wjrO6 zCmG<0U3nrTz`9LkgCAXg!<)1mm{W$sEfkBRpD@bS(#6g|js5v-2Gh7Nd%+`itnxXg zO}j$aNshA-jMBI9I2OEv$Fr7(#2-2&TkYA*OD=AvQ8FBB+!hK}+RMJtYMMoKdx72; z!~+32R#B@s5t#95*ns!~JBBa8WX4y+`K=%JllatZK0)Mu9deq)zobFwu?3fe+F)4_|U(+nMEwU-%2rhkaPF@q6^gf%= zeFbL-&W5Kz_C3*|WLjWn_o4x&V@y$Fw0hr@KcbtAsaBH2la!8+yG|~T_DmkuEoRgS z-h8dH&gmVj^y8x5*eLr!O3tbFRUg4|q?gMlyvMY@!v!jUG%vn&NOP^X>@qH{o4gdsc2IH6FDn|C^eeKy-6RRn zp%U;_&1Pj33vSh@PlJAJT|&0iKf!{0p~@5@_x$yq_^=9u=?vmeiY^-N4Gggp(NJl6 z=w{tUoRtsD%XMmMljTS5P0?C1MC5@KP4Ut`=Sz)NJ6m!IF~-^1Ti-`jJL}d*RqzB5 ze3Q6!bbYB0yBr@R3+6cw8(;~f=z(S2W5=#}#`u`o@=sfw2~;6<>&?EHA+|<{JBOcg z!FrBz!iV)tAR=FEeG1gTxD-8^sImt64MNQkvfcXKF_*W*4&TYF{*PlAF*oUE@x?37 z&G%mGjLkoBSy8`P{8R}L=*)fjUZb5|JG@Qvhv?nMvR0AY+!a4BT)Q65=mgVzDw~LhqFfTA-!X@ex^KDuI9`{JVFL5ApnEjKh@iShkl9#YN zBkK!z$pWLH%pPa38kc5;bslL9;S)0Tt-9iLCv z|1lUQK_KQLg_wR{J9BJta=7GISrhv_+nCSNyCuHg#lQcnS=s(8|6d_o2fK zKKU279S%c}6$v2J?(az`ua45e(-zR7bje}s@_nTskHHSI|CT*PYV=ioXwB))zDu>m z53zecirb;ahbE|OJGG}X zgpZUny^9nb%K+L?j(O_`v{JT>ul=)angFpYNyBQz5pI!=60&8nO&2DYj&Bm|CEo~hzWapYZThQ%Nn_K~q%eCi_M(8xGENrn?9Y)oi%67v^` z6Bz-kXFEXw-lh(LSIe@}h@&$BGav12xA>Q07urpoKV;lb<*QwjXZCdUjItMpqI4xs zqt#v2wm@h+{z7juWfz1i&}0TrBWILjRXRy$<0Nao>N0a2UzC9Ll`0Pb6pDg0HM+51 zdWd{KS9*X2zxse&12++$%7xh-Yeu7k)QVaX5tXd$y1xun?<&8i?^1r1PSCoNiN7I9 zkV>l&pUlA+mTaqX?xnk=G!)59ShFrN=$|C@_4G2aT^m1<3C}9Nuh@~?F|O^kA|d`e zo+$nhw43?%PQg;gg>7%x_^J`z^XatYrwhN%*qIqabLcQwA- zyo;^80*(BhaR>--wc0&N$|=xXTvrp(>Ow13HI?5e2_dggs=W8R`-DovcElh028@wc z&x6X;BmlZkOY*u9J-mRB*|dmIY0wypnzpzyd|~zmmAqxDYzNt!u5Z7jOB(hzE%0x9 zsk`;P=Dfq~eWZ$KF1B^;n&R5$Odsj}D5oXga?|Snmn#3G!OpZ(C zcD=DwE-9b$0^gN}*c|~CsyB!AR&R>WpiEC@Ev>mZivd#$r#2v8*WIUkN*T18ufj#2 zh514x>BC%K)cvgLoJgjbV!46?<%~zw+z&{*+rltpiRtw!!0YJ zhUIG2e$IICCDX~Sbz48eC})P>jnGCR6ZIX@6&`Np1Y5O4jBL}963_7NoMz&^%7psg zB_Dkbr+fy&hCZ4{O};LDaM)oIbR`Am)*%~$t&-66H~ea2E+@xP(>Mrw_mO|r%othu znV|Zf+VP3sg|mlwd7P?CX8fzXxd%i&Q$ldD#|S>r6j!7L0~mdQw<9&43V2N%Hcn%6 z6umg(1V?^y8D3d3337p-51eQki{_?Rj=M=ldJip|v-Cu(On8?!vQ{1QV)$%nohB|Q z=CzcHefLLtO)Vi1V!xmK8o%HQx=c5kD|!lBhCUMswX(R5(h zCaFVElB30NbEeM^ok!=j`A#=K8Nlo94PA8^G+~tfqK*jc8WJ#tk$W7=a)wfz6pdTeqIu1C zx9HJXx6H$jZnlp*22kBT4_Ri#4mfQq_!YS@FuDl;9sdqqnCjYr6^On(6R=)adlbQc z_2`V+YvTl3*N9_LSnq-KOJpn~r-R~5kiQz#9}R5#I-mJ!eUyRNzB;yd*xs|QSaAtb z-yf(o$`$uEe5N+MNw8sg3h##z>lH#Q4);V^tS5{e2r6$;-s~wbRPNxu6+R|7;P82Z zQ9Fx;4BOEyadlEWuRBet%Vha|Z$O||(IykXrdtnJ|LS1jJ>z5^^lbI2h&1S;Y%S5j zTFTk2;}8|b>>gGu$=0M}F?T{)LKAk9X&bFU@yD_oQY+HKTivsr2)*o4Re`krR}AWb zeDQH8mYr@&bdXNK9J*8fIaVbXr;GJ|O-YKwgJlb2CC5yO3y^KuYVHucCUT_dgpAFv zCT@THS4rq&zV9wydV1plDu0W!+0U5gz&;%5M;gEzN;|EY#tjX@8}}(z(vHPsX$L)u zfJmL{PQ4ZWRHe@PSB_2-5^-UwUw_N}c@b-6`ug$fKP!>MZ~3va4en44X`id$?@C4? z8Ab+{E@&q2?%m`}Z=m2%xLBULeG8)+VdrWno#YO+s9OVll5HfGvkhac!&py_U@ihv47hL`=O$cPi@j<@?lK%QGe^j?<(b{-i!7g(xfNfb$w}mX>6PUR3!nR4wa88MwGJX;n zun}u01AAA*yg-Zm$L;^X`ulx1xNpLV<7$T&<4%F&p>rlpV3=2q#9gg-V}{F!3u|P% zi5a{k3Kr2igKqP^wu~M-WgPT?e>lW10qBf$-2z9g)LRV>{p2S^Q=(@zI^%)i_O}vt zu1UDKJRN}Sn!b7|j9{Z15(qEEwrlv1$FIi8i8ZUvuGZr&|Ctk-$>JV!$1A)4qJs#> zOqloQkSDWrON^l-N9Y-c8wwfVD`P*;mpguzVw%g9VlvD-+s*nMT+CjqdWKDHVWCTH7NYHAl_YX`*wt4Io*84MGxql9jj;j) zM@7Q--w3sZ?8CD8_WH_#tfWhY;_XB&)D;0y>D;aCyLOW%xSMW`dN0pSMsL)V2OoHS z(&d1+R%It~)<6y64rsCSF+PowKw9@t-F6Y?fj&5x%IURpO0_td<yT>-F|Wk2kJfllNrtTI6%IZ;)C^rW>?J&+vBt@Of+3Q@udI^LyX$ zJGbTk;xez{1R9|_+Ue4pnoi&Qa;A&G^Yzm4mjFS=pZWPzMc zN{Hf?VsX1v!mr`Wj?)3EC~|)tTUPr!0yZkgD#n$8B)x6fAfC|8Q-gDqsf9=;PT>&y=i%Iuzq~aHRAQ)z=5}JNt>-;P) zWUk&|j`tbu9N%qzX$ z6cJ=3L?NL6=;cTTwkCum za=XO8&8x5|mlXBVv*gpdpk;Td#&WK=vCrm+mcY6F@zcg>edng_ie#;`>vg?*>ymqn zRvj$ACTf2Wcak4{dK;^o#pI+KCxfWPT}b6Ac&GuQ9;dmxOe$9SxAAAkrD;Dj!YuXg zQkLVr^;1}@GQL8S5<1k1VU#m%{cYCQGYN%WM=m#L&6zZh(~U z7kz%LQ^|7muuRz4zT0y}W6!lSBC>wW0Nt^|XIffhDg9aFoovq$d});7iacSgUX@B_z20R|}qnP@t0H ztLn8E3#gU*&#HA`&~>_x6X$y6K9b$(Ny9EBW5-t2UT)I?;Xycz_iQRO@YuVQ0XtN( zCBEQ=Yr5ZWCf~JHOe>lVuBzt0(6}KAq?ArwDTgDEzDp9i(%CBRT?x{Y7}v5Kzw&j^ z>32k%Ac41q%Fh@7V)VBSayz7ZFQS;ia}8$)(IqdR+?ynxa{M}_&~P4pzf^OGb&?^lZ9!?&B_f?pT zb$_kxjoB^!quJbVVI>bcB55*9u^`d#K#{dQ$A5M+9?2Tb9@Q)#;_ydmS8ALn>e#7< z)x+Dv>fc52iu8D|G^^eK@gd`(p5mK$tAwTZv`2HjWXkZ!s=22NLoyDJm2y~ms;BvK zZdYqt@ij~Y>IwZtR-SY=>{Om?REwA%y^(HUxDF1Ha4DOxn9crtT4bXBdRX&2x8n1O z!D3?%%*Vv4X37q4TA;BCy$Q$4A|%7sZea7|x0jxz%ak*#rULdf@GS%Q2h5-|+n3rG zjmDKwnE%x`Q?~08!hR1l<$C}o^xj2o-+q^Jl^l$Jr&n5kJSn4o`!JLvK&Y4Z*}ZmB zjlF(R_Na`TfPH_YhQrL&eATGTD#Tsdk?*s}ymwOJkhRHU;7WfEd(N&m;9Ziz&AM?K*PWpc@OZ(DrJ^SFo-ma65GNW(5 zT?H(5CkjscUju)4Koo-W~fgb2T)LavsYl)P%|L?a1-}@R7U0s%?lzmEGSpSLY8jQ$1 ze4*Rm3W9~<+OHaagV@7bR=wfzO4RNIVkF*jOhNKVj8841t+;s$dKxApeDqX$C{A+M z{05=&i#YKmyJd{qU2K^W#wwcSD$!Rx!W-P5PfQhXSscM zsOoAJ{8m+FnmyF6?j0NmH`{c(h^p%_$r}V-1ETXka7{yko2_MM>Mg~sut=O}&95g( zxuUQWwTWT-#XGTMr9- zSEdeKA>OQx75Bbmn#;SLKP|#=;tD*c2=3?eRefgP?Pnc(Pz_vC4gXbFX$}(R` zRr$VQ@x5%0=Ila(qa%V2ZgnbcaZMlp!<)Xg08FVTdP*%%+-%KnmFIBX;JEbnRAqTp z&ikK<=O2FiPaOUtsvGmqRW`~!+ZL_cgy&B{f@gy--GPMO$znRQ%G%M5kBERIhqt|E zY9%XdY}Z)omIe6ld-W{m-*yph+E<|~(u*2;O)2X|72Bq{s<&li5KbTDr<3^2e5Q%z z0oUL<52`*bm6yv9xeX+#vQ}|wNm(Q1(99t!URRF!&^scZ0=B%o6#0HI78WE?tJpQ) zU4$XM*c!ukM!=a+PiDE=h^CNy=E9_=kI=Lwe=W-m84Q?@GwEGZP z%9P|_JEB%mvOZdE%UC&0wfIPUgUaY7%PZQ6wu>^z=Z*Pf8xdKQno*d2`)Ja^Coci2EhO?(sqTh$>{*wDh*|!T~~=(p;3XQXoqYup>e$KeXp~p zX=#xhiJ|E^{-25>X`oN6o1zO`Rp*dO~)a6%)f(|QOtET=8) zlcka<9B<#>f}hoY5I~%~WV2WM`|CqYFN+p_9w{)}OlwVC_x~j0qX9Bc+n(fYV>#3= zb`uW;ug`oLPw3*hikPeIu;}dKGBKgtqL_%?G8JJ<47IQ3Zv0gGNS%B^O;w38KI;nsC*H2AFG?6fG71NHBV}@S zZ0R)@SZ8B~g|?m_)eETd2WdGjVx$tQj*28)T81lsH`aFv5cwnd7NQ5V4v)z5HBcWT zrbMo7*9{XpHwriN?lhOR>mR?jM2qfNcg<~$p_du>R^FxV08f=@bkMCZrNZx*k=~SU z-rc8*OL~rrJFXmv415mynuUl(YQ<5Et);IIK?$ZM^n140a+?%}=dx|$@CM!y$#r-k zK5l?iM9jtG-M8pnGbPQ=nRfdYHMa>C25Rgzj@x>`H&@<9>Ev(9Om%HP?y5WFcXeEp zI-h-nR>kaQUUi^O0p4@2&uUqGw`}PBz8`5Xfq|pLAU!h0Wg}$D)+TWDNwt|ZG`zyM z6NS_U#v7^z^}FggZdKYW4(3q=(vA)xD~GmUH8`uPHfOASX4|WE9d!L1UH33GC6Xxy zsBK%7#Y6TcMKd10@Dl97WXBOzyeD#`tdta3YRb@09KA5?z4(c@)D}f-uUIMNYuYNy zA3l1}xS8PJUYJp#I%4qIdTw6oGliB#B5!~Z?(FJq@)8G|#f{275_^wt3&1g`D%TZR zvC90xktD$D{`UBOm%u{(K-7h!q3ipOkSJmOT(Pv-Yk}xE zKAzibP$f#sZvpCgE7MVuN%`*4Qog>|G$#aX&dS^FXEnr!hjBvm*9r zmXer-^{2EF)h1AY5(b&+@3`oc8S0u4qy&=TkH;)Md{R%?FJwePW;WWxCkCds#_ zL+je92!zW$SdTprb~og2%~aa=`ZV#B;NOvqzwYVECIG`~wyIE7L}P5acQ2Y2A_hy| z$f8A$#DitSCNha@YR?*#GWpW*(=I=!A1sob3^sDkTJvO2u(6nUdwOr}I<#x~wSbgw z^1f3rr$Z1$yUaYZsC44Nx5$J7%i_*ZI;81x67fonZ(bu6nplGe*WFlA90VCoxKHfJ zYaSfNx|G%YE{jzV(^yz!P0NT97mvZ&s4e*GyXw=fhl+W{v^B&G_PIVAjv=*gUV9-# zayEv4UpP+qUCV1>WzGqp(3hYCg(awq#yrb3P1(j-Z+A>+O6k}wx}^7L+Y(YI#%?uH z#bM?xX1hiHj~Yw_yn-8Se;>S-bO^MMGKOpI?K^G|6^02`m%IsBduJ~aFQ60-hZcUH zo1#~AI6eG`*vN8k3bt^ylY^Dqf(?QIo}v*-qj^JHceDZzy(Un-X*K zMR;;SAipaX4Jv^s121i1w*oZjzgx)LStlXjR%HQ>xhEz1(0c%!rUq;LUIq;nx1MP5 z+#DUNk~kvb$xOK>>rgJhWwtljyUX_LvDQIlhuW9@tirU)wz!6ZR?snnv&{X=?Eby( zAvOHR3TR@R2~pUUEIAdRvCTKIbbNK4-w-ocGMYG;+h7;j``z~so(mxvwz?JQ6Jftw}x9$QJEVOFTV7TbcT0FCu8s`7P9$2C0SjgvM)%GE9 z&h7!fGU(4$QC2QxcCA%aBtvS{_Wa)n1}v;#w;lwTqY>*P!)8zF*nMVi_~?tV3wf$^ zq|GLq3)Kvu&nTAd!T2u3penuam8cqHTqJL;(oevr{x}S831%&t;DN_T8NpEhHR6>( zU>8x!iddoL2uFksCS#zh?V&|UP2mg8qC+pzYd4IPuX=p%E4c;N3NaVH{9aKM!ucc$ zg5$gF0qn^C$1ii8;GaxfeKvYU05*y*)mV@9>)go{g?U|@xUv+vFz)e2tcB-=LFMS6 z%W6=Bq8kTMKE{VY;)S(yYbB`9-kNbz4dwf)aoI6S#QRCZPusynOALP943$jmP7vvW z4bwd1>U7={yW`iAVb2tE6*KVjG7c(IvgHTju@%wjSD_OEH7sP%5_ao$Ay&wH>+M6= z8!+*hFYzq`5i>pB|0=3wO1OEktTRoSrhOeGDXyEMjqukElwkdi-G_hIIz8VF93xEr zJUGPDQ`_94P4JsNjyPw$^Y_}o_nPEK8EK%1vTDKM=n`SaGz+LwE)Xh5^U4O@oHi9r z{|w^T;MMsfwQAt7F)k({RWtgK5olc_35fQz*+(RNF;XkE(wC$f6Ny^*+`ywd3$x>7 z+p1*yP5D2ccJ;bQ+VVevgxt*9v=r{-5r@f8_r8K=eE}_;{d6YP_^yeev*MFk@H^V$Q)PwYQ+y7E+3wZ zcLKw@Z<}UxPvevP{Rf9}x3(k`+w>Q;PR!dmpMw~^88(X<1adRUL#Hc;eN+3!kGTb~wa*!kK}y7ETNP8|CJQV{B)| z(>+y;Rw{VtbqmTXz9e2;fFntUQnO7;DVLFw`f>B6A>P|_b+5N?dEL1`My;TdC&zTD zP^Tepc*kn9hCjOC(D|oN#0Xqr?6YQKN7Kd zXhr>ESLAzCn1;9XU+E*g`@YxVOW!>xtEi2UpKR5dUVzWXD{V9h!_YnX-ZGWeD~CO* zZ5B@siNd26@6|C)zTXZF z7hec}L96uHLus?hEbLgdtFLtf7EH!SHDh@gzrg`#=bX>`q*?KKy%#F~`ffi|@D9tu zKt;444)mYlPP{!}DR3^AMbC%NmG@jT4IWn$43i-tuuE=XF^@eokDG?DtWn}>Li=-_ z=dtHNAoI78q*@*a!hS)beW$Gx)e#l5a%b)%T;!UH=2FNF9= z@x9E*uYi$f%}T7t-a#=at)GO`N8QQ9z*%4`{rf8i_E3KBbmF)m+DIA}71^t$rAH(i zgf(4h}Jtn07uU5km1Do)}MctVf^OrX*Q zzJmxiD3TMx5aU$HPOxewf)B&ibfbCHPmo~NI>v{X);A<1Zm0z3D+`w)otyHC{`+04Feic^!gytL%^tGU&p{*G#iTjK3j08ffLPCo5eJ z6y_z22iDnwTEV{KqF^B(eniO{q?w)gcR;v`u|M*lJBM!ld*NVUN*p1ZEU!K z2@W!Iel#%SWMZ4gDEP&!7ZcxfX`fc>b^HGA&^_LGx<^&niXk8R2p{-Mymv%`i`owB|0_!6;P4EjRV~$0^(JwXDy&uP(h22!+wi9;IbIR>*Iu;Xxc(>VI zyIbpISjiZ!RPa!$a;IK7knS*lWN1zlrAuxHk+Y9xM{cxo6!f2&fu8|Uo-{D0@_ zJJ78K3sz79S} zOwgb2N<<8wLI9+v*d(C4Jz-q7GugB?<}s!x>ps^1NwCOEv()(d(4eaet1DW5=E0i( zD$m}aCI18m+~-5cAusdAb*NgMQOhS!E83>RS~J2tz4&!-Tx}foYLcbbVPe$wXc9~q zMub^#&K+DoOZauVN6Yck+Z(Nbfk@=PVR-_CU+0^_wBU^h?88Ma(o_gY4|-YY7Om`6 zKMC;C!5n&f)L4(I%DjZL(DNkL$<#T>jziJ&MV)!Q&hGA;p-d(rIdS;!dc%ozst2y| zs|5v^3{pD6hXojH9f`!<6>q9}9tU4sm$x@36UQzoO-z)lxDsAk&3AtbqKm?W3e-t1<$@0A zf3M27V1sh+s|b7Es)jA(Bb3K!u#MxP5B%lPk6M98X%<3gow?`gS*+2$D-YRSto(6q zcY_ulD4j|4C0bp zwT_gDDeg8e^S6FHh-R$>1&f21g*AQ2_yiUftDa=)GNtGieuWllS=;u z^=MZ3rai$7Fv+ni(x|VsWQ=hQIeDlhBIZU>o~3}5{k*mb(dQ}LR2i^CCK_MH;Hf$9 zhqt6K1C-x9^e?7o&cM3U6pc%I%qEaU7SJwk`=pvlkw)WDNx;ERKGY;ciBAXn0V{pf z?y(@gtPLUf85YGn7?|mX|Gs`suDa@N`1a$0?YOZK-#k9F7pXT@daHM|)6R7U93oJ9 z;f)w^CK9Ez~>TOZ8tVeV6Rl zU48P)#z`zOi&4>NV5K18DqYFIG+%KQTnmG#9h0mrk}Tg}zlT^m^+K&H>?*DuXrmq5-W%GR%M?7Lx+u zH3XYK<5Rkx@lJu?OU!=Vt};)EfF5`2ZA!a)?D|EEA13xcU&$dA7$%3VS2&FihH;aFQ|})b9D0asO@N%U;td^XOz(LbE!L@+R$u%-)p?!B1cD3$3XYn}@+tD+5zy=gmaM9v5K9n6dY6ZQ0oD9b@`n25~f{%a!6O$PC)G6E?n z$uSOuydF)uokJW1a*FwdOT=f60KKT2SKv4AnlQa(R{wD4&ymx(s&OA7XI*$qhgBkLP}r$TnE^>-vU~Z&XJ8lhoV>rR#&;n;<)@|i2ra$u@wKbMHilHrj&ZAK?O+dn@H!3%lEirC!Q>h1$g z+k>LXrvt3Z+x$ICPrN{0Jf&A^BNzL*V^y}o9}-i2F)mX&c}RSQpNu=#v_@-Z~1E^RaE%xK(e5c|zFmuGt6gcfS5YHdlVI)-#yUERy~p_aS3v_m|Ow zlEF^s9kkZ{F2nI&wp`GE0FqqM?sLkcK28c-x##h*q34aPF&08& z6kFJp5l!AJhio^KJTm?*pCT^*WxaC6@03qUc-?)A(_PD&uIG5|x?Q|5o}P>LCszhS zG9{%$Ehv|lSVbp=`8kwB!0n0XD&T4b6q9H+IF95kf%2nsd82rT^t{&)XIkZ{&M8w0a_ekMqsH~XOa zA<<2Rs9-FOv*!=E<2}m2qz9Y(EJk+u4R=BU=1i0{z(nksoscn7>3||jdW-y)p3h6@ zRmH^%!4Th0NQML#pZm?vupVUs>SgfmCq7)VK?!m7T+r&PE#y?CX~M|1ew)n$6{d9V z@Q!)|`B|wiFbvb|tpm@%ES72lgRF?XJRZ~GIm2DbPziovF4+hOc~JRg>VHN=IN=O< zFH^4U{L^oH{i?*&$gt4S<5)HIVDz^Gmiu;-`IrB$TI4I)^>?+fFJVGwJU~BrA1h6K z^b$I~6pV{t?6=~XMco0pfpsiIpz73nOPW>mnvG}Juli~sg%5r)|9Pzpa~iPWj6Ml0 zEkpCXn*K9tmj95^QNg*ohv_??w{Q9oJh2>z-Dyh>;&4^aQ3Y;1#4Bvd|7@OnWCyRl z+Xb8f((0A(oyK1W_fsCKA*@~o=|?on<_%4dwpS0+nCdk7g2tDB%k3rn5-Vj?K40HC zxfb!BZ=;8M28T|ww@C^0#($&}25K9M`V@5Ih+gpCu0ZYi?e}!zhSqPJeKnCM@HdZQ zk*@Z=KOva;z^w0sCr>&c=2Y+fCDf`7)rYO0YFGXLpu41|=#!)|TlNVT4#=Gp z8cH$y7^&jt&vF17HT5B+} z*l}Zy??L5-6F5Lhg*Ha-jAxBwI}lo36i)TOkL80Mwa;X!Wj*9!#DO?B;Ah4Gal$$7 zdr38%XBKww%HJjuhMIp8%b!U!KOmqUOCDri9s3hTKsw-YFJw~JfbMxO&f(kDOculA zk|yhq(T?vUl1`Pp-k%}8x`DW8rRTWx-&5*1N&#dr3+lkn8e}R<9XZ|KGVl#ZiJI44 zw(nlq+}=FYi(QicgV>*9`wzw?7s*x$fX0VpcVx<6G07|Q;gUB;A={26OUdXg=GF5~ zBK*u9j{E--TRa!p#s#MN`gXBCKtySiBvoM)uM;Pq+U=(RfaN7#mlfz9WD0JAZBQDg zdORTlv52ei>boebUwmX)DmO9QumIar!1{|NbLQgHGY8TGjHus%_tQ5h#z$_J))eS7 zM`a-$LzAZyv&Rb-Yo*J*Vkt2?@6-XUqYfB_-RJZfY=oi>QNeebjA+3s2F9sSVPc0Z zVl+V8NJuG$QR_HI<_V5o_fQ%_@x#=VARm27JXc>>q;vX&(!Z?vW446w$6S%s)#|?l z-edJ7Jgu^$*P36shzl?gn;}0=!}v^={TFR^E2^w1AELMKC=J!aR0Mu;*L3+*;8)&# zP?20c%@Q7PRo^|TPDt%?EDbcy)$-waYJ}lXA+wXno=Ua0J;CV|FB4q29K0>$#@Sek zdWvme$M$6c0XMlcES!g_EA8J{#ZTj$Y66h$ZtvWtQk5(p+Jo)k+uPvJJO$oW`vI$e zFY?>(&!FwiMSPLbg?nrA%sSwellaqLiq>}5{a#wkq(z&8&WmUR;t92HkE7Vh^k5Za zsqIOYS|Tg2EkK%&15tu}brQIUVb%YSz3&QZYU|qFZVOgWL3&XU6sZ9LL){ic1wll5 zsG%vHNC^;7u>m0w>3s_-(hVgLT0|hBM_TBhlmrN&g%BW=v)KCm=Xw6;?AvqoZbBw4l>9xcm1!L3l_E^n)V#MEV{HC z@UUUn@)6DP4Z&&VS#u71)2*4`Qiy4UOZM!5pHD%RN(}Qu83q-l9JzH*h*nQIKmyt4 z*vVe*ayyV~tR>$HkkW!CAx%!FFx>6h^qb_#{UpJsOw3=&Oxqv60;9!9U zj#jwGj)2V09|rLl5vGL>xhjLVVP9rLjL?$TZRF9RH}XeWZu!Td*j&U)U6ud7JOAEBY5=DEdTV8XE0(@ zrCr9YKgkOE$Ifd--%1X=^Buj0{d#T09+eLDZk<;2?JO#yUd(xC*piG~yp8){tmQm^ zu}KSbX-958A$$8gFw3c7b@4D^b;-5JmBn|?4>P%MLLA1>w?eLU$xWE`fi&`hbcDP$ zo3DPc`tfR%%3njyM8vfO#6_f!Nh9F~s~lcZLx7LZJf4*9M+IrDY{fZI;x-HHtlJ+w zGgJ^yfXycksa{?x5K-u#0#!e}HSY5LRWe<$g@3}{|~KE{!{j?I=qC6Zt~>J z0mQ7!3|>b;a=7Z_m-RkRu-xaqDdpYnG%`Yyu#xQu?N!xrGFip4ig7vvH5*2LnJe){dX zm*~B5))gQuC(i=$>KTD(NuwSZ%`>*eDeD$&aTeF8BOXCGCU?N^y=!yp@b&tu;*vIJ zvpy?G8@>4Zz$qTcn`1f;N2+{jx4hpUE<%L%Fz;>*#%4V08BM;=kr6tUXKYLjvEB{M z@7(CTLuSnnmX6I{pXh$QrnRd@*Gf@I%&y3x8_X67yWQ1{C9S8d!X+$kv-PB^ZF+~J zH=eMw+=g=IH%{}}hA3d`=j;mVeUsPTm8C{idMIH1I)#uPUwm=EX-vx`wtm3QJ^aO^ zFq_ncA}?!B!Xao+cX`+FvjOQt&_sl_0;N?tTOsjw@FA!bwP>g6iGsfqvi3@ctxyY; zyaO#7NvWte{|oorBW$QntxB$BM+|v_@Vx%Ra7a)?fBkI@ej((+@H?tB5Dp3Cz;Low zVM1oB#!@~8U)m9-Y3&8?vys|pF*{NBo zWr|@n@#WR;ThyA@SE#YdaD=Y2rxFpTZ8-7rHX@huwa&VnigJQw$Vcs!QZ52Nu19X{ zB}Ns7Tn>e;X3Tg$x%4f4F?gI;_7>s3NZ93W6mKeJl8{PjWxe?z%ID?zZ9zz!C2|;F zX@XDA6XDeJD_}oxDeB$bM9O`D2#%Y1DqQswl`fj%N{bhAV|U(^?qX*VYniYK>P&w2M>&6YzrG@f7WpD}J3Wa-2W~)m z8#W5l>NH*9q7jLijL<#_aAR;6>*N=9^5;*k@Yj`%A~6%W=1OZHGH9QP%mfIdF6kzkt?Y3rd z9a_Q$Rq)noX~$ z-NHObyEOS}t}VZ4D1OppSF5dFP83NG5p65p)v2{7heT__;R-7J#}37Mt|V)?d#rW3 z{!T8~C&_oDa_NR+>dh6Bo|M|i5DLUOpy8N1`}ACn#VF(H;azs_3jU{F9SIY@XX~3x zkJWH1U&fKJ*X57!p*CPW7;+s^Ypjf(dBogem1#<^lzvz&Dj2&kih|bb_~&93ymu( zcF|=IDA~0J=q|)&M$f^&LIM6t*7v>`wVjC1VRh{=CqjQnld7?1b}MZI#1hnqnuH%Y zEq`-P)wrBCiirdfwNu6R?(T8zKt=2{vppV>bDnfji&y0FH(=PC{u$S|42$uPGSc+& zsP(AXD1a=+1l4uFFeCMlOW#yB<-3TtgxY9K0@!&-{`!)FMOJy+62KUG#)rDjHq^V+vpPRu`iqGlNt3GyRswovBEC4@Va z7n4s<<~fSIv8|Hug-~xgESlt91T8ey44G)Hfmau+O0cBk1pk*HsBs!IG-rH>gyA;)w9$tVi;dj5KWd%fMtdCcly+IgVxsV z-1`M+@K|D8|M|(8?YlK64=I!jnpihcAG|Janz`Tek>5B>ilER-1%-gQd_Bv$TSstf zc^VW^cMqs0mKn5Lv{mw{E}#poSGe1k%!h-!Nd;ZF?7U#;zU^oG0>pIKdHI>Y8Vs`F z>rm!PRFDiaYGPgZ1nu&DNRt+pQs-k=!X6Uyt>J~ljCp<`mYn}<5N)<&D&<}+v%;-X zDTbz@*7d|?L^($d6n6ewJgv4n#NkGVi%E?MqT`ugN8s7rS9$VvgMLos(zdR|O$XwD z*MkbJ>|;`i1a`d8af5W?%JH8oa;!ufhPAWzy7c28ctOIH8m)Hv zsS42N?{y@xp~ZSR#P!O})^~>$F8H`{TAn*1LNMkNtm-pMX;C^dH{cvl{F( z%;HNB80o36L54y#Rg|5_=T`={?A)g?x%>3OD0jy}Nz!4;l-BwIAcUqt!MR}|T^xOa zAlI!xM`x-MLcG2x?v)$W-!zuthTPDa7lRfF1EoNT;O~{C<*cd9eSTv{Z>#QLB>9DAnpj~;rP_1rf&;v=g_lS%v^{a%qO!Y!&IX#DEFE05xsFBN0ZA?hsHZCy>ReSE81nn865D!Dm`QYh_?<8Y9SU zqgdy#(OMn7h*Efws&p^M(xNsg(+dT1QY64SnjE(_WT1VjMTR%GH$IC);?r^}hvI|r z4|effX2*PnZ4W`K-x22)#|Bn0koWFdSBlU#DcY9NUtGizyer6CxmSyN6PI3KCL$Aq z2#w|+wa^x&EO!$*t2>%?l`#4=qgqLjW~LHSNUr%4HF7MI>jeix~EHo znmt5nzD-(i^E2;8wLwEbd23`H{z*c*nMP{=>K$U%bn|Abdf?Rul+GMq$EI>lX%--1 zUh%V4If~8~5nR_8j-k7_mj+1pjq>>PM@^JBn|E2Iv^y1T_eN}RcT97#UA0=5c1X+* zYM00IAVhEaXY~Gi6GG>y*SE_*Ztl&WY5*ex5O2M0r+}4)O_y(sdPz=ZjhS0U39&6{ zKRyx6$Bc{Hr%PL3P6r#CeY0$W;LJp_&80ZweT%WA`s?rie*fz{$3GvDf8&t@3pe!Vuk_7-!Ts@{ ze12#1A6)Y9^sip}JMrH?|GfhLy#oKe0{^`N|GfhLy#oJVufU#nvNaNj=X;eyFMG)U zA*-z0R4v^gN1G={_Ko1dq1h)#2aaXim7l-IQ)nc<4tsyevixa6+{1^@uRN0uzmB|h z32GlV;HJ1QF5*oEczZ6z1Y?KLfS zfl_I(ot<64M?joQh}u!pSyK_y6JcZESzHzm^)uF87qD&AN_Bm+HQSh{6a@F(`TEsj z`r?+R&u_)!i{|$TDciB@ry$n%Rd7-Qw9jJ_&<=j~IY^;&>PQ;kPSvqAduiBh+R4#j zKYP!gO8jw(#P)$AmC}|!SMTrnOg7|XyVC{~72)|;miD|kX>U@T?~I{kow;QMCY5KV z1a!w3068KnK5C#*Z7sC`@XAyQQESDbGy(rk^nZT9ERBMXtW%W+28$Enh3=gL%I*_P z-$#3~;{sYDPPzG*_OhQ`_J&+Qk~Eab(81P8Yt~Fn^E;wDYx3I@4``m1v<(_RQrg z&#>o)FHa0dbO>F;$UTl6E4sE>py^BTQv<}HFG%}-m}?5fS(%PtOC&R+3Tj1ZL0W=b1Kd*cz@f6ufpk20`p9k?z;>jy1HDa{3(x{b{ zOw8KDeeJBH97cOWSfj7DX93-A^*U{UD2nXybzmG&_=Q!HOg#VLXxPh9Q$gjK>@tO1;$C*>7r-<4K~=t|eu7vKdOPdR?asWT@5vEzZHr;+Mr7 zpP`|sIqD?5FfF~b0NQao3NP>gFlbvU|t#i!StRMzABfze6 z9pL1FaT4G3S@OVI&W9Sdz&tGqpsrTXg3P-pd=#uP#58Yfp185mxnD?z{{A#^L=l!2 z^*J?Xt_e#28J6lzZIL@~KnNn4BXjiyUUMayW0A!-vUQ3ZZ@9gg*5hS1G;6TMZErzV z{SWf3sjCLvh`}$8z+-$RZe%33%jtm3#)a8W7!PGYTxa3q+b2PVGJ>PQ;;Z-?ZqE` zevjYGn5+daKU6&~D;y}L=p~DNj7^ zE{gYW9SO2{f^@$$6>iAW((lYeoeIcKi^T(;$NQX6h6cq3gP&j2rd4S&X4*hz45{AYlzL6(j zbu;*rnyC`6pA3H_V_7&W!JsyXAuIS^EA;YskDSzU)daLM5-U3X>}Y@x3w~1bD0D}L z>jD&EKd)gEOw1ld;GM^(T_sYk=SRvl$jg>^RW@$2V-|wHHH%$v4&0?`e%yX+KRsq8 zh0d)pe7HQ?Im6mIU&J_X8!*075fhF-h(EX2Fq@p~V_Yvg<+f2DF*SjiP|c-5vu3QK zA^tSHwj`s`FG^AITEM`hwv=>qhd``&Z0&?ky<(G4>L00slSxIvzhRC?8Oth+mv2b>EN&1RLwSOl{D! zalq{9yt9KrXBn1S?4-xc;_~1Cts`jd-umW2wQtTF>aSxl&Z|!n=p+5Rf3x20C}|V} z0?ELntAssIbMr3G;P|?jJ&A4^C}Y{d3y(Xbuy1%Pb3!Y=&}n(+;6oj8ksuhQodUL4(}Dfk-eESQ=H4)~#I+R(&~r zV>qSlBk97}PC07UCtciM&Q~tKgg&A|tujJc>a~mah#LkhBrRYTro*bgTSX9;Lk())vjef0Fiuk}@0rvGSm*^o#8LusRs&#V?qp6+zPIFX?Rh(+3$2nRY zMziP~DGuwGq?s?$%zKMdw;5Q__y(ZPO{}%wIbM2gm_@9>5fhLnDy40ar%i>1j*P76cfzvNRAe)$^+t;&<9e zPo+wwN~1$*lDip8Q6uZ=+2Nv7m9}xxXXz0Z#XG~tir?)-`y1RZPI&+^!`vm)33@?Uy!u9fc5e!{3r1s`2;Wi*DPtB!lR$BQD zD_qSYL@uwv21c7JO$&86%dxRjZIx?wG1OK5NgZq-z1c0we_)1h?a*dmyO__!4cC3U zF^&Z}V7~z*Si5iN{*X|Vp9WK?d1DaV>{E9JCrgn;REWr7-UwNlTyS}B0IFybJZm1K zUVcPJAMYsysF~+^pjm2R9q(?ECU*J4M6GBV^!uIh*~!xIsNz{|{Ih(nuSsxsSu90Q zd%YWo${IMk%O83iivC8Hp5Jn&V9q2gav|xqX0u`kFw)4DT`N0?E?^$)nKfUkUi)1lJ5hSY5ykKd#om?#{Cx7Za-gVq@}p z>r4njNVCI)-mXC=7)#q?0r}aJ2^jpjMQcZZv&N#uJWRuHZrg2rWhcpPXKxYI*z60% zhhxxRlg1?^fU5e!=gM}u?B=r-{DIl(kt|RJ10Fy0_MZgN=a}N}vi)1h#Ht>}0W$u< z4q+>XbW7m%Mv%b#PHx55yK8Y;wRwE>tjspXn_)Doa!u@bby zCUh(OWA>%)UH%lANI`Rt{q$>_mi=T))*~JZ)tNvyE0ccS);Hz7cM}SIqJtXKC3w^N zj|)YG`q8tfRbFR8zLEQvyny9PtCQJtOd<01qztswRV+^+_$ju8qFh;8XS*wL<>gd? z(FNV(iw;`vvVYvQqKeXd!fnw%;o|s(rp%%#+&p(=sHGb*J7ZVI+Yq)=!%_WYC*>!? z*z7q7HgxR*^xl&{5PyO*P=zBMXWZH`6@>_amhkO@7E|9w1>0}NU(WcA^_PySd0ChQ zoX-TW2u?N8FtvE|3h7}>_RIN2wBxjd27f|_LWE2`#7 zzEkp0@E5iv7`(TWp_GU6yOrSIT|5J;>=!p&DSBLo9G2e<8l^apf_(vd1OfKwv1gBD z%LHjbiZKF@6q4V5e_wv6JR!;<0%@dYo% zgyEfZSMH%V{%2va{eOokMdHle@ZYc2tt62zi2_7M>(yTpBR2*YDm}CO-sqt?F{{GK`z<9aYA_I{Kb`=)f@E>R=aND?Z{Z_(qM&< zJuPaz#a!J`sYbp~Pz9Pck+Q@16DgvTIc2i&l?>L`W|%8tN5cLHJD0qD9KJYh@2*Jh zd`Q7e8?AX&2F2c37ZMr24(vs+8d*cEovTO$`U|Z^dvEvQmg5MIF|&6+3b*w*rUHxs z3Azv2V_sk5$0Ncb?!A78!IItvAYCUU?mvjVwsrWX)n4e$t|7REy_8X=Oc{49Q zd1nx2NboJ1Kh*Ygc&lz@-^zg5;J6^N9hyu$baS?(y2Yf|dgPEBP;-9^^Ft#`R{ZR< z?y_IP$d>XQW@BPBv9j@oBvJ&hhg()YN+`I46zm?V5GAj%+twz{-3Yx;KB|4%y--ru z?$UGpIKx3U5u5tgPlwULtD!VTypcQwYg#DITjH-j4%-;MkM{myw#2A795m@Zz}mPN zxENpl%$_OqQ8TLCa}#vMf`^pTV%z&r$n9?>SFXrP5bcnNmq-5G&~@CGI#UbArFkTiUsf>Dnc_B_8$?0RCvE%f+@;knF;-p%<` z(@x1K$Jh3C7f3gYe5{&-c7F83S}c2?6LICDP8E9HwI{QKq)ePHx)k$ z-cE2R3gOh|kJ?d&ZkAgz24sfg^+%(Dk!D#CDMj@>1MYzELI%yosb(5zyte-zdwn3f zSYWKws9<9H6b z=D=gIcj@M~gQfw0Cxw?2%DUtW`s+B8iKZ8!nuymIY_sj!+1yN6JT^YFuPoHRH|#K7 zPVI#W>#SRnP*Z=#O-uIUK1*PKhxl|w6tHMqD=cWG%sr)fT!*r z3@+SiT(kQg`u+zQ7Ra?mnh_3F1a99l*|sMP=wdgV<;R?u@cfb0mq6u} zEdcr7nc%1em+$QF!#oa-dl4mK*YsGSujGQitCVRASjA{KkA5zHQ{I<($w#|qC_`tt zeego)r3~HF^Ufy*W1DV`@Ei9!)Fxq5&ELtB$1EGvP@aDo9djN|0eM{1(RQQ`perQGQaLg(&k$X$uQM8Gfz-xg+mtMwLHYVJae!c(r;Ws_cc#TiK5=h>s7SH1b z-FCemDHS1j1DYQZ%`dL=mk0D-fr@19_dug;!c8|X{a%~(<%=^P`3OSLnk6z7Tsr2A z;Ydm@Nq!``Xb{Q>W)0B_%1IU^IE!c@B$+5IUjY6A0ygx0fw$h9BAF=JAZ>l!rcDVpjT*@ndPwYk%A zQf+2`Un@H?`cmcZKAlA=r-c5QL@Mn3Cctz%5** zWxJ|x@()2S1aL%6-Tt)3heukGR%CThKHA;T8WDy$m+hUwZJjzYqO#ESBzkRiAn{H1 zn7STf)PMKQ=G$$}=kGAdFq>hdwKSUUs4*gGSp9ZVT<`IRcQjOm)275!r7q41sP`C)Z7=3^mJb}vD*;f=4$wo^Kq@~`xtNXC zb^8mdbKW2A9=%Y6S3P}>`E08MoU0_(m0aQ%f?BuqpL}~mnT*>68T6(yRN3|(VX6Zgk7$h# z$+eT(Ld02IX zzG=4%t1R$)i8PaR?oriO{r)Om4|_S$Kz-Vx`B;F`Jc_$M_c9P)8|sXTkZl9 zhHAzQAu8oV&N7|xsddjnWf_}YZWTtWV_BMkGYbz?9&R05*VGY#$lf@oP-R$-7j?wDm%xax_Y9+Nx<`vfATnp)I4l8o{ibt zfE1kgEa*{l2uidENCl`7j4_?DYS**A4f$bD^Uv`!(zF-R9qoy%=9Qg+kuR|rzPH5I zIt^0_#@BPbJ#Wo(UGP?7u4V)k<4b{%0n!jrhjx)dDD@?-F2`N0VKTY2qcJZkP1PAk z+l+O+5i$CSf9Mf|C}S*#sm&Y+?az9am84CnVhlW?&O$tPlKj%yf}YhJ8?fiEI-uhh z4G5G>Ky(89EDx0)J5vSYOpgsb?H4t%aRp)Ag=orbm@W*@s$(1y7*nO5BtWi@>PSxM zX<_+VKH;GphDF7?nnir~q z{yF_phTh6L?pR9|DW*9^6t?R(u4|0Na~178>pZ=ClBBV=)&d39X|c(U?r9}&k-6ec z@;}2R$bCmI+z5&Vb?c*LU*TEDi|Lox!q=BYyu+pp1~c2G+L$TwcyZcWgyy{l?kAxs z>t-zj&!;g#A?N*NfTL6DyOh{=!%3Zz@3KzNrc7x$4zgK4R3961ONRxI@5*Y1`ea;! z#ZymluM`GMc+6_l$@wP9qd_lBK@XsHfMIs zd17@`jmmfYs{*JnGm)DmKI+piz98+S=fglz{aSZ4MF|`6?32WCW}{V%)BC+4_lrDZ z;6i$)#0~~zBTcn5q!xJ)$V+u*1XiXXMMDf6Ib(9%kzkoYF<9VJ5g^Uzs3$d#3z@rOAleIbeXZRRpvv4NrUN6L_c0XMN@#`wGhj zxJMT=Lq6h2FtOy`4i}#gm~~6y#$9}ZLvW2`U_=^=(?-atYNU^5RP4`QQN2q=r;CS1 z1fDLAhtE@}AgvXhTH)u?VL2KN)mygz*U~j1C$bog()NX&_Jq9&0oVgV~J&2shxqAvTSYo;t#AMYJLp2)Q5+mR}-QFRs- z(g(H}7Dh@HclmNd_eKAmnO#%VPP?n%>bI==!FXo>O#daIs$c)^YufPA8ZHsp{sTBk z;O8%^s=4dNB~FzTxzRGPrNqm)l^Uu(X`jrZt{U->l0D9urs^fbs;ip8(K#`sPkqNK zJ_kjOJsj*+`lM3>HdAa(cX0*h&}!lCosVD@*273$=Im`|F|&63!h)!-R+fyf&4cPz0*ugvZ4)CAK)lA^hlnl$8~jLOfd(H zi_|&R3@+?0r0SJL@F?WFIhP63yGSPq31Y6T4h)rJ3#W4@EkF_5a4k zJ&&0f|CXIm7}QgXQ_P->YI~6?s^U*ZF^0 zKEC5Q#k#Op)pm<|lXTLnONp3MQ_6!E-_|^dagXK$FQ8^)CKA1A$x2h#z+`flTT7fw zBWB5TVmWJ{2Fi1&?PjlC;Dv;u1o7-#^KiRtDK-&-nSb|;jQGj|6u9^?$ zQP7AYVY4`vCv_CDNAB_9pSC4UhwGGFfCd>WI*UF~ZQF#Z*{6mf)aeRJjT3J zNdoXRAJJSHzpir^f?FZbjoZsnP1z$JD~_Vau#au;;(Xb6%W|5vMiZ5rx0fK}lU^L~ z6X#*%m>Z)(cMTBf?L(v^Qvr?r_*Z-FmLV*uXoV5G{h*{UBr73MIKUm@*` z{b%MNEQZnvsE7q-st*S^6gBKS#VBtDB^-evJ#8?Wuhc>j9E9}(nvgPW<+eO;p!0dkfxTSTCmR5K>evAh2 zJA?L&2jX!Uo(|{vZ7hKWt7%;t6fhL9zGv6+qx$hS)s=yU;(%!dDU_|dXnG_!XqdKI z{{EUZH!+sRdbsDJVDi?I4(^mQya+m!-0G{b6`rjULYTvbNdJ_a0Bs3_Ss zgcxjiomx8AZZGhm2>-D)Nsod_2I~<%nJ3f75f4{w!bb4x+VZ8;AHV{BbQJv$Uvq*% zRGIPDiDQuyt1pxP)Hyb-!}F{=QR;pT$Vgn?#x)DH+^N2ddb2FC@7&m1etG2XE503W z!fyR;{kV&>roGbf_B2OU?-kNrV8KpSa|6Uq3Klio=m^su8V9FvrB)Y5gr1l1)@uJM z`_AUPuHnbUl2!9g<(#pW;4KIW_r|nmH#RQOb9QCArkc@p_et=TX+22Dva@??pR;jaRAxgL<{Vx3B1Uc2tb6zNL+a@5f&$(CfM#Kf zIot}NJ)SkCBspmbvK8_m5%IjWyy>Ew&NWXigEYZg0Y2MhCSlNGp8dw-p-!pt?iyED zZqDZ0Ru=t%<4Blr%l;?u zX192foTL_at=Md~_0HeoG2is!-8emJOFA<9GelQ{U9#21;r^Pw?Y`6$GBdw!v+Xr1 z2Qq*y4CzOXLI{!ap<3VgGwMWZPn}Vcmk9M~zS=`s!XNK9-HtBDy&c!8nRr-1xy?vn zf<0$rTs6N%(e7)ju6n2S=38s$h0JSSO&*aSnsA{H0RkpWrvE62FudgeZmQXM{IH#0EaaZRu)YX%@n%yJMq=yING0Q)k6CY1 zlH`ba&l%M@U(*d--W5I=wEKAIG&__s=Xsv0?;tnfm zzahUaBKUZNSB7S1UjD>KLvILCn$69M)HLR%jVX;J&h+TX5kH)y+jWnR(IS}8KC`ee zv9Z?^+fpH|iIoD?%SeHKK{3y<#uplAiz{uP>^jRea#|$zBR&Rqmd`Bz#7CM5-D)<6 zBHNN{UMN4HuABx)F^eH0rzh)%Xm!TyGFv7w7IqoP5upqfbD6`0$QgH}6GL{$*QOoR zR7T7vIHhg*0atyqNe|JIH6tp;)PvvTA{60W8JPD_d!=fe!EU+>`ix4=HJqGNWjeHv z$4qP%FW#qO&?_&?aRP1Uyfz#_4*QOQi7-xzHSQk#%40$bMwZ`sYq>|b zO-&!fr3&pB;61Liv#yJB^2iNQ|DW#{h1(FA2~nJY8v$#Vv`n;x$*>4_m9VO|wUlvZ zr25eng$6VF;O?pMI-x}$VIYe7r%q@vj0|@_ z^$nX@-D=yKZlpv;dekdSa*=GO<;SJruey-RK=2!RqI#|TP4ItG=fgI%jzHJquRuG1 zP`q-xHqomv$*~lSvkZT`jZMobbu_)hl#Wkg*ZEdy`v_(>SAGsw=`6lQR(j%`wHe^L zRvScjiNQYZmkb-QYGA!%f(tn}w5&KER5%x}MYb`eXXX9n4niIJ_gX-vI2WvO8(7aL zpT-Lp>S!aqZC zX(p*P-eY)3cMvI?31VB{U0X5<@oY?8ew_^v&c1K+nec@y^SzX( z!MNio@3~Ba(2S;)iFvR`d@yRpTK>+;Qp|05&~OSSgi~28G=-E-jFi%Hn(yi@w~p%6 zE!J%s(2JliQVC{kiZ`-vV39CDha)aSVpM`_Z25iVXU41gn7P_Kn*5rIJ|1&@#UsH! z`tI7?QY+R}Of9%N2HCgnoyO>xxxV_i47BPiY+JK(nDWI0t{==S#!%Fio#tI_@M0iZMq`uA@;pKiXM?d6l86XiV_RhLDf};of%Zn=l^Y$)EWv<{&KC zCRnwo1A+xTxnKjE&H+iH!JPL5U?NTNV4#?xtAy3mDu8Nos`zrpz>0wMCj-ZmmnoDB z9u&D{miWl`>6z}O$32EyIX`nI&9kMT6SG9DvVk3Qz+MgN07r^`S{5JLYaEeWLG;kvbmzkg8SdnNcf&v@qlj0Ol4GyS$` zDf+|j0{X#29}h#R#%cb|U5xB~5w_jt0ecr7(oy+6Opd1`B|+Isvw*8_RxZem%-_{gqvW8L*&t{gcn z@X*vB!KZO5-$q}4UaQLx1noi_nUiIwM^zviCYbjfFqz<-BgJc#6R*F_?Re)&5&OL6 zP_vf!Gg6_fP0lm6H3HQjEE z@p>_?_T&eV*X8J7&E;^T=^l>Lu?(<(ACuc`Cx2%IG%eR(ygvMhkf3eGYaG&=w1_UZ zj_%Y=%oa5Bm|K@7$VIPjSBA3fk6Wz;#s*3R+0VpOGA5oYED9X3|KzaU*hf;10uzM! z^4I&w$n7u%XQUhw6q6|$U8EEEjSH*r>4e@;-$r#qzICdP))k1p@{TcqGiST$TnO&f zgpG(H`DF$yrt*XB5j_VgSg=r6x{EK{d7c6?4P&Pvb1^}e6;Z`EE6-`PsG8jp(Vg3( z|1>5ny#Q&QIrIq$_kcBnr4y?-^;?{T-OliNZR)=S5!LyBwr`ka?=5rA7++l3FoZH< zs+c7>=hlIy-olpk+{1<$*On_@xe$}yKCR7qki+VigH$L7@ zh39Wh((D>p54H_34~~x|kM}v(Nt=k-Y=2sSM6%5OF;?c_cO^kCZIwef>_ zEXmiGS8S;mE{n^b{DYLRFWatbj~M@G-z)(-GVgPj%yi645bF?NbXY@o-Z_eB&v9*&5>>$=#&ZDhL|*^<^Wmdpj{04B#&$zu>@38NBp^_C0>4pLzLrwX0@GC8 z7Ga%grQdscO5X+=;5NJ$SJh_>tBgX-Hl2WD0zJ4h}N~Q4j&?4-S)a&{mkDCgQw9W@SQ76g{Q713gR(kZ1d<)p9 zS{oAkL0NX_t>wZA8<61A*aT=9dkKBhAVhI)C{p#%{z#;%kJQrhpc;OzrPZKkH=g3x zHz`j?Lb*pfJAaBHC?4i7_ww1Og=n;G+%w8B9=X^Vf%y?PL4QUqjm0bq=*)dJn7EHW zI}sxeKg8k9M>t4yvZ=o1?Y`-LY*S)9c4;e7907xP%}WziIzd~l8KYT>ex(zC2jcD0 z1kC0>H9e{iG}blPdi6I7dvnR0`*oK7l}eq^_@twfJmA-E`&&5x= z%vtqYoN!L7RuJkD2`tuH*$6-NObuG$dMpmiNo^@lC^U#Q-}@bS6+LqrRd&{%wU&UKhG!MC7CIhcqL@zyVTR#SJdHQ4xxfo3HT3H?k9oa6D$ z3QR^2{byQSAifu<movHhhZ>&FMBUC1cqs5$ zT+whJ@dMYEt4^|7gPXw`)!$Pu*mrYEdFjiNDavmgv|y6(ob|_N7vYxV)JozrtQ}Io zmZDaq7Z;)QT&>^uwQcRGmc$0)*Hd4@hvUO(^q4l!L~-H<_J>!~Kh@b9@glE3pAtoL z5XY~9O;O79%^NB0m8wv6>G4*KFTjRG3DuG$iXs>8YSR#C4n$(()&X?En+Sc7GA9%t~30|2a29YL=Om+%?W3=Czxja!?`?AS4 z`w!^#%ABUJyG?wUEReB`?u`xfR3E6`g-5nfuge!sqwaeVd@Mi%eWu zTzG#t=9NeOS;4hf;1(E8RR+xJX4(}Flg{w*D3NmA=fZBth9(TI?pE849-|$$FiwJz ziyvsoRwn-3mI!WA8_521_w)X_H#Pu~=-~-jq&$% zTQuij>%o~yKIZUIbm10!{X<61Cy_Rq39M5PE}VL1O6+923Dn{4h^WuQF2BZO&(*$! zRW=CgKv4E{qRD``cLzh-Ni1q|9nxISutf>e_z;?!hRn6qkOv!K@l-H!1jdh{V3^6o z5;HK~f&`uhU)#A>&##14nutr{?cE1vcLID$HE7HNU*mh!8?(PO-KuB#Bo7dqU{}v> zS>K)5L6r=j0(<>UT4c>Gz7JT2Er&_V6HPPP$Zn#H%Bw5sioO)k3hdk1kFRlOt2h_E z=OW&C=rAl%KmW>sGV;R1_ffx=rzujO1w0LpizW#XUAb1Z<%)L-*5S(^ecf*?Y-p-9 zYH%pLiZeV$VAbHZfg!vZV+!pYRTEBg>!pYVjsnG!0 z-+RjNfUwwBtwv(R?oB);Hd>M96ouFAllpL35SY|3}#lW_! z3?TBH2iv{k;G=g$mH`|4!Ls|yHBg>yBjKmOf0Z>dHSYCDyHeg^0blxm*gFrfrn0T? z2a%#6Dkvb;-W5?mIy#C41r!t!k*cE7dj}OO0_q?|P_O|aHGmYQh#*mEB2}u2fE4My zehH9!?`GI{-fx`uj`QA?=h2fKemO~2cGmf?wbx$fUIkmDxq?X`sYBDtn923d^M*7t z4gGS#fU%%N@urT;9bcTPyLci6OIormzb02(+-tkesX3?ZwdqPt7R_eSdXaSXi&wrz z9$Wh%&+z*O(&xUb1`_XxbMBDX14nX)JWFFmNmf3p-|myY&p?t*>(;JbeyK#6Yl0na zt4Wa-XO;5z1vlykJ+CRM2(zq#Z`W!6Q*{$?#Ivh{I(B=Q-J+yXHnix~KhIJ7{My-rmuK1NtyzvH0rm~VfK z%^~t{%~$BOMMgy6Rnlu~S@Lglugk6knv^#2)qDq{lCK;j|MJ{t2j}&^jjCBwEik&8 z>{Ir02|b_lmUyJ7_TIyYWbzN3YvKNTBggNut$Lkj7GBNo$sli>AC|Ev}!BU z7QZ99o4Q$^=R4+*Ay6XcX&#m1cgcEIrH*?}#H*Tv-0pU%`fo>9E!(VjfWG9>=ITs^ zmWvfF%G@vIOA^bMy|XGUU|~C>*TU<_=Tj-kSF$$mD&=G;Oa3Yi@Xt0u}b#$tI~}7NM6bet%0X2^KOxL zI#<+{ZE)oo6Ff+9_)_0}N?y!et+)Q%z^qlR^V|xCX4d8;ZV9L<>cmO zYB($FvZ=PNqz7ZuqOOcDRXXaQm}@U;TF-9k-Fe4Gx+zAtKSPvF;&Z=M%i6lG3#oHw z<)ycN68ps4ca`ndi@fhw9T;YbvUhFZ?sKtb%9B#okBG8}Z0ymsHF%TclfE_ip~J3C z!F`MlGwO+p&d;^Eq!_o%N&Y~>vBVMfI?-JxD$R2|ZspS@y68#E+qC;YR!Hbo#WhM>S#L>7 z>J6)Ic$u=WfnfjI=9Bo+hS_m+W*+7{qvtR>Me)4&5V}`N;7)LZV9hd# zPHDP!wO^mt-pXIssTRAzM*eLX@4`rl;N%T_uHsICn>VF8&VRebWi72`=CyM*A#H{a zSJ)UYC!deY5A1$?ui`_%UFm@r+PZvo#-ThfDnnYlyMlSSOSW}QmX2k1jQPTzNp6(0A-nwP)>TfXZEchXEx#z6s_;Hj(i@}g-rKO7Qu{HkqtE5% z?DRh-u-9=%dIG0ZgW1~^|jyGVpp}({&Dky=IwlX zfrgIh^##|t)wj+@?A-3q{+h$MJCyOlFS2g^pZapcWi~4OYF__-%NF5bhSY(vXT9R~ zfp>ax)A~NfDwstVoaPA^-NBa}6*VG4sv`M@nsDptxkm7W`8Wi$bgq+xqCxNj|4Vg~Yu_3W-az7i65tia0N3!uweFp1y|o<<-X}HFR1SRY|Q^ z$PH9?xCBV^)tBqsluBihW+AtwD^X4_`}kcn{^Fj~JeMYcfE^p7G8~c#9;)8izs|5MT9ZbLj8Qp#B}{vNrmx~1)1QAZDz&#&1zbheCPRKDJh z^FsOs$80UjYkl*1ml?4ITRrsPtPp(JYqNprO@m9R604!EzL7+hY_~UAy(QG-b@Y7xQ!t zCvmvhog52b4P5V7U~Cb|AjcfIv`N(_Shsa|cXsU{m&5V+p8dPF<+~MFsk;k*)O8>v z)u%gjI%tYXc)aE*Ay3p;%OqK@=P6t@^1;P4dPBT>h#b$_0_o?2at8TwfpUQC~8vRy5qj z`a<=a)h#ol-agFl@*mJ$!NN)#)ohvbEqS+4>6U8_3`sWor8)=S^(Dq%3Hvr+V<_v$ zd#Y96I#97MmhYKy=ir$B*Jqmbjb+^u?B?GjOZqiF7#g4VY8OeQ@%zN}#qiTJ+iu&4 z>Wf$Q1?F4(=g)P|l@_Lf_$s#YhX!_)hW|4mL%y}I1o>hd~_sXU@4$7{%bG81vN%F;Y zpFbV$zSerRV%gTLL~*;jZC!Q8HtliR@Va|3abLAtR@ zq>cLN{q;`gb$5vN3U&rjenE3y9V2-!AVtcNe?4c+3?w{K?m3Pz)HLY}b|v#=HxrM9 zRb98~F}M1XawD0+{(<7Lfuy((&E%$1R%GRpKgQxQa*iWuUg{momKlL+BQf{Ly_kEB zbTsXdd_5#ky(-(h?viC#ajZqS1W8?{-cgI6yO6x@&vR{eceAq1>lI^}QsvIKPLQwP zKK@HD7Ol@n(;F5fKNiv6VVrh1{%Xg8XEo&Ru4NbJq>OywQXLa%t!1LT@6cZq(*jN! z*I9g24J3DGmU^adrbn6;$=_kh+UX|~HL&W$x6d3hX~nBE9T-3t8OBf0l~6B@3QM>!q)vNKH@7Nqh(*UuFiSSB*Dk!q z$Ivm8_ohdR6;Ice?c!Dp1{X|n26!$>UGi-cEU#C*{ba6(mz77OmuS||j5{o;eVzprX4JNTY^k&DUx zD;C-D3&~%#L z^vLzl{e0NwR3&qk<9*%T_m8%#hw6QpDHW67&&d2stm}84!ia68haQ(?4w4L-i+63h z!Nnd~Ozv9Pop^n4<(QOeSHoh8x6_e+NWas9CAaV8CLa1Wnm7LG`I*<+=A5vUE}HBD-Y%wNl*zJ&lC#H%v{Xg3VjaXOb>oGyh~t{&dyE zK@Hh^%~uVj)L5*yIYf4x>Wt8`xI0px#qd(PO|xIp)M;p+P*lNIV*Zo4U+iTAx!X9Z zYI+tLaSXY6gdN>e;TZ6WDEN>hL)TcABO!7laOky3YD)sUm}bfB{CfdMzBARduvKIg zu#(HcatBU6T~+@vnb#>^NitaVx<#8@w2Ew6LF!9WL6PJhQO$;z)~r&aM@7qCEh^tW zswv_*TE`{(_}iC`rDnW3!>s-DZN){pEW@ui4yN%8u7BO)l5Cbg;5>ek)41+HA2ph% za3dqFkf?55pr2kAIHoZeD7rgf<(NFVJF~otZd&F#nHNLzh5{sRHpsOxSS*bic)`|j zr2iRPLb5S&DR1*PpHXrfb+O)sJQ5d=t+Fi-eB0$G)2wPuZ^<_zS*kK6Ib z*c`sUbQz1SA~Q+))t24lzRBVGF5)tuxkarAB&*Fu&dP%MUbc}f2J+U+RBDSwJ#05r zC{h~8wlX(K4qg|HXHAgKc~94<8n8}cU187F2GbV0{+anX_8j;0RjXfoQzK^Ox9czJ zY2F@Sw_|)w@VcUoMb!;st1HPLr6J4T_kWPw1fpqEP=SKPqbdGCzRz8c$dY(Ug zy79WDR^(P)*N|kV9NoR)Tiu>%bv5cAZ#bnnueRx%X-a+?f5|OPPfG*2fSy6=F&(Gg z$Q44a3Yp?NE9_rdMqGJtH1Sg6Gp)eXk9rO>{pK}?yGQP}Ol|Io;>hmNwcM_Gy!NTS z-B-PJ$7$IQUg6cP;8e)6c|>|o^wE|X(7ZN~+Uac0VP3{%|J~Q=n)F`L`nHr2du`5P z<~FU*Ru7wrnbIj`2ftkVpywQWUqW1^)c4Kt7i;6A&KX`>@`WqfTdlM*u&idiZJhhT zE6v}eNBRa*1gzYKmyqW%B|I7rC$f7~9U8PSSjI!spk&2iHUFMDZ*2az8iN*d_1OD6 zXy-{6AB@VBmZ5D(QR>*Tj?enw_J-QnJ-4_^GfWn->DKnWb_~c2Tlh(Ac&Da#iCXN& zl7L8Yb`ROgoV%h&YVR9c?_jggi@Sg1v!|nxJx`0iifHL))qe8gqUH$Vh1PGrQQNI| zY0;MHEw~q3^DU7pZEoLKhV)s^WFLoBg3V<)r9?Z8oD9K+ym<4}S*T5`x(%9l-m3S&L;o(-hulntddu$dKd>718b>0RK~?J=vlLx)RSw%6Kf$}D#Oclz&0D0@6n1X< zkxnlC4dL`duO-W~21iW3wsr;D^vv$y>)$VKHJVbc;>73ku(Uz0L7@Jz$GS#qf4+gF zcv`K%O#K&0aaBe}4)?n^2pHD#eERjvq=V);^8`L@lfM=7iZO<5rjFck z)oTl6cP-ey=e_LlnFaE)3@*uxYnMK3-uV2gk^48YP#?`OtLSc(`hMrg<*|(6-Z8P^ z(%2I6C3FX)^dd&WKc>aR#5h0J`&FRIymHK_wr`t5eSueplv=r$;|68LI*9-;X^w)d zetx+#;=zTAoqf-jKNqhtGj8z}82EDCFpDL++--xE+}#WJ-iQqxC~}M7?eZg@i`gbF zmKx}~ski#c_{5h|;kpmpS!Gg`32Qo+pkTJbinDP`%DKkp)l|=#MPzc=@1o2Rq-%w) zN%*yJdB9uB6dKJ^?=jn7o=ZMkc)c6py>O|iUL zLsP?}ZB(iyBU&U+A6DhdZQR?x=$OF*j@JSkH(g)Dquu-LU`Lp`ZG71}d$p$SHOD!{ zj31ve7~x!3;wm`&q=NTt4WInO+*`i88s^q@=@8#IoqAGxB>B+(MI>LHcaqoQY~xMd z-rpNOsv))~iIczK9@D$JBOR)eMIov8*xo5^>Fw0cNzybmu6@O{dRlS0_iEkG zgXz*-VIKX8OKaCV5zDxasoxS$J9aEeZZLTd2n(#lOfc z#euWpR>#XSiHG;*XRYEnDhF z*Y>6KjmIi0*&EG;U!{u2bL#SLZ7dWnjOQhloYFrssu0&wvrb>KtivHEG1OdsL1C+# ztADd6X>ry{m*~}F9gNrOwb#2Z+GqNXJ=H{no3wEs?=@xN8)oWXyu_0i=yiHNh~%u@ z=NqGGF4}O>_r;PX(RdO4>{H=cj}3?`rJt}VXEN)$`0V|vwle+>tvr3G=UBH^uBS=X zm%Ti?L9W{CS>$Y9SiE0eBB(`j>W*Er)~M>r{#|RcqGkI_qwE^4+iQg`k{EO=_RUe# zJkGtW(=eWn3JZoE|s%HnyH@>qD+HD@c?h$!<`WX4*#0E!Jp0v(< zexu)P^0(GVBwqy4&LY1voANvLo~MRixy&GjdqYGK^e+q0=R zwwpUyC30_Sl$T?Ky2vShmLp>dA%g43bu+vq?>VZ2Lwgbj^}?-ZRM(JSX7@QFDWlji z>3|wXLInAZc@T6Xy%cvkMLDE43^%{>wY<7QKjv)2!_O*df@U?EZ%6L*JoRVjNEnT> zFz#&FS>j{cyLZu-Gdg<0Lc9jn%*&HfM`YfnjxLNelFLe|Ta;V&d{h0vR_|yX1AWH_ zJ?F}o>$9$CG4P1I8m^rv`KrWwkJQl46S>}IdykS2VaO>RzJX^IDMn>2pWcWhTWpko zk!ZU;YnI08tddKDrg8?GRlcxAW^U->5Xsnl+#wyOH}Du zFLUi)ah!I4w8Ar1X5a z)~S;&v8;_TfUU( ztP_;L3GuvvMi60xV^oWM-y2|MslMJ#Jn5CCdc{lHH*j@ zq2s+nUOMM(=YC$Du_;%RbKORD4#OMO3qN1$-C3{urEK}D!eST4%__qmS-r-51qX;q zlD?TjeGB8(Y#!svZ;aTo;0BN0K={ghAI$-F-QHLU&2Kwy^*1GC3u<=emhEfMBfE)! z!_hX&Z1p`qhFx~ZNw-d`I>Oa(eVMM*H7n-cTV>|UB(-iTTwQLZQh50@EqANwtQwD# zciZdkT&-Qpe=@c9;^DWc(u*P`)A|iMBmK$8ykjOKR1&jjUti$~b@eN9+@AUG_aEJI zS=H2V!K3zNR?(`;H};lT9^#cTy}CKBFf;G$Y4I|nW3T3UXD)3KlO`Qx7EgT_yO7)S zUj5ObK~w2b_9~xYeqDbeN0-p4u+H7CMCNqCJK-;EmOS55)7qC?cKyp?L1BG=;%f!E zd@X0sbHm$2h78H4!wr}7)vFb+gvspWckk;WPtc2Skn1QMx2oTB8h-a~DCXl<@{iI$ z(4oF_)HdGyY>Cc@I?+Uq$@6567P%MeM`*sQ zj9HX%he77seHPm-6fHF3gv;5E^MCg!ieRzrefvPc@hw-et4}m`QUa+JWJ#gtB^Z7MUpD_Fw0E;1{g zQ`uTB&U#+tcaC*s={y7SjLPAgWxO@7rS&m(5A^O~Ep5F%O1tzz>Vfe#$24^RXm3ny za~w3;juzKDk9eDL{7+Qw*NHB+zrk%?QEvI%-yq{Vf`w-x$BSp5p7Sq3Ib0j&o7QN* z+*6Znb*b%gC*IZcuK|0(0$>5K09XJl02TlXfCYYQ0doGcWQo2v&4SmaBaHNqd@}_W z(`Uy@^7y}A%V;%+)-CfiuHtcq*&sm-fVp`fpPDk0Obm)bkIeNSR?;-G{X&LSh37o-_B^ttN}!m0AW@N~qOdFS z5Zyy`579kD_YmDfbPv%zME4NgLv#<(Jw*2q-9s-Z=mqt^-1-VqP>_Ox6cnVO zAO!^}C`ds;3JOwCkb;5~6r`Xa1qCT6NI^jg3Q|yzf`Swj^vs8z`Oq^TF6{7=U&jKH z`H;+qWIiPGA(;=!d`RX)G9Qxpkj#fCZQhI0%>x&0V!X*kLmVK`DG%H70p21JyL!Ep2AP_78W#mA#uFNQmogmRp-e`C6d z9myysj^Tn*QBEDh$)%&56NYQcK)L%E?sgW+y~1!}Z&B_mhO5p-IeMn)?c$P$a;q`i z>H?IL!*IEUC})7-%t}zs1H*BAM7d}Tmt28zA26JDHOh5kIQq{h$Id*x{laQdP87o( zm~;SCzpIAfdcL8@bHH$Z%_tXu;bdA-?j?r%+KzHxFx<5+l$$wcdb@1wMY)w2uCO2F z_Fy=hA(T6d;dn<;&JDx8B1||G>h}?e;q+)x?mdQMrboF>3`d-F@YL5`z%sr4RG84? ziD0;)IVh)!;qK2vIXes|%Z74yF zCJbk|4ds~Wrnd|04wT!7;Syv~?f`~U--B{y7>;Hi%H76r!SW~1_>eq)@JvnaP7!|52JoC1bpFhMyJ3>R*Oa=851Z{9HM7`K28&G(We`rb4PUYm|E z(m(Re6j)539V^M>|9UMfXoCf9u%HbVw84TlSkMM_nNXJrb(v6?33ZuJmkD*5P?rgH znNXJrb(v6?33ZuJm-$~&mkD{&L$#b9pUa*oNAZaa1pV}lFU4%VK8z^2>xy31eWZ{A z-RU5i56OH;=0h?clKGI#hh#n^^C6iJ$$UuWLoy$d`H;+qWIiPGA(;=!d`RX)G9Qxp zb7);u_tSlS~YXLXXV#A6C*dvi++oE}#kumNY}D-p}=$gzLt`b>n~f z-y{rD7^E;rcVCC-9-@1Q?jgE|=pLebi0(Z;s|wF~OrXPexV z^rxSKfk6s`6b302J$DV~mzW*39ja{|4fBkE){oHo@pse>6qrDP$xnacfI$j_6b30& zK|vLiiaaFqA(;=!d`RX)G9Qxpkj#f|69i5WI6>e9 zfm3HT1Wph*LEr>|69i5WI6>e9fz#b&xkjhZEJ2#Hnv?mj^rVNBWMydxVgy@PMgryLUovZa8#H5lLs&j{VmtMJr^P6@ z3&Sm2hH|Gd+?y3B=ZfJBSEF1whGSiaa(NgoVFSvwV>tCqD91W)szoLq(`-RGAq-b7 zgK{bu&gB=Bv%zqyWl_!#!{zQqxnvAyCWms>7>+|8s+YZ@;f6P;N7ZyQYV7hcMj6 zvnXeU;R+2<&KJYk7^B>C499DRa+MhFl?BR;VmLi(lv~U;z5ST&Q0^BDM|42B6Btg# z8RafxxS{hX_XNY;zld`0Fr4falxx9oP1jJ4Wx@1zx#5O#n=qWv4U|*Da361>oCSt+ zx{Y$)7;c#l$|YjBH+N939K#vjMY&-N#~O%od<&%FgA@iS z3{t51gqqJERX5;C!IOd~1y2f|6g(+Z&)bzj^*mJ1L-jmV&qMV*RL?{8JXFso)m_sS zy{ua-D3JkQW&H#NTKK%ik^Q|f`caoPYRwCJSlim@T9PO1eT95TEX%WSUv*FM_~B~EFXd8 zBd~k~mXF-2O}R3r%+mL2$fS*_k7V9In%AZoSn8c|b8B881Wph*LEr>|69i5WI4M1c zzzG5;2%I2rg1`v^CkUJ%aJsB3D$-OGc17MPR3Jgplw2|#?sxg%KQ8es$ir>fRGhIg zt;pwC0J%ql=#NGcP?-;v`9J++HVjf2q%cTf`3Ni@fzv%KAA#i~uzZAlXAW)pVkY+H z4_YSMSnh6uzzG7U|J67Vik_k9`KOoQFi2sL!XSkL6DTnG(Kr!2DR@%wq~J-xlY%FO zQavcugHk;x)%!wj)vhW$=aIMPku_BU#gyuU|7fWKXj0Imph-cKf+ht`3Yru&DQHsA zq@YQIHo)=`SUv*FM_~B~EFXa?sQ+|M1}gKRGXJN~$-p3mK?;NPXIwsVNJ&yNTh{IZ-YK!_jb~ToHx~=0&+)47YDF%5ic}Z@>1XC?}5LyjGx`I))QpjdD&H zu4XOD-N$ejH=x`r47X+z%6-Lfd7Dv=o@aWym#bNSEq<_4j9f=3FQJX zoWNm}dx_zSj-cEZ3}>r`ax?j+w+r8Klv|16GBia5MK&L;H*j3zjAj`XMJ z4UW`3v~>>|6&f2ULd0w)NZAaH`f2?8ewoFH(5zzG5;2%LV7!0C{Z ztSk+IpWt6Ii$J-JP2PfLj6Wpo;hWe_{r|Mi?D1Vx?kt9za}wp;FkFlt%0*(hBWF?W zJ%$@LK)Fr~_rMtC7VuB~q!W*KnW3BrhHJJ!IaLhz<~+*TVK~E!D0dgbv0g#BR1BAJ z4dp&zICVFao3VI$yU^S~x#bux_!i3T!f^X;qugl>*Y1sSt{Bei4$6gNIPtqEmxtkM z0#L3U!(DuUa;!@T)85uRMmZr2mluq3Dj3c@6yCIw9jniMoCXj0Imph-cKf+mF?qR>P1cNXSA-~@pa1Wph* zLEr>|69i5WI6>e9ffEEy5I8~L1c4J=d|{tsQr$IO(aXBULT=E&;ir!iq00yiQW&Jr zWdyp6{Ae-*JSlim@TA~L!IS=Zo>XvM)^?tkrWzO0S9>PYELz`}v-HO6r?>BIUvxrn zP1tQEc2D>8FLaVpE+?Gi7M+Mzm6sclJF<1&U`>y$x2AQEWR+u6s+3FYozez>4Xy?C znGJfvbzS|fPG z@h+dSqIGG#$f!Z2j2k-(M?;}?gRf%Yj3B4iPTea5#e36ITF$0@Q5P?9*t$CV^_pW212U4Y4(k{j(k&*w%kv$2yYZRWcg3X*W++ck-xM-s3wuW>RpIO zqpyeXy~|HGa-^)yP1Yoq2=W#Zp9a_!UfIyIuJ_Tgfg;L|;KBpNbq|jO-RWCbA|9+O zu2QUQJQz)RKNjl(DLYCmxSl>&?|v%O<@8#OWU-(0)UHXMKfWlc?1oXDGG&LKf=l-N z#oNviXlBf0ocABR<1oLUaP*Mr2n~UOFy4J(vIPSTVfFaZVVW5eI}S`~wJ`NDErE0V z`STac5GL9%Y$FIU5roEQCsrWSk@r%LG=p~HfJ}tNxp4c$Ll=}=qh z$j5K!2h=e$SrkB1{lj^OJh>Dw}P^?oUBsL@Pl8?CHws`%WP z(O0Kg*E?KTZ#SfS^jK{(quoGVXMSx}?)T14^_J0NPLdjZ`~37s&Czcf*i>u8 z9y=Wl)Q#0JYZzn&_{Wci@S@6M-iJPXwL_LVO7EAy4#&<6_7YL9+3Og#-*D7(_6L{+WD- z=nSH>AO1bSAc8>zg9t)=2=O7rhY%k^dp!7f9E3FpYY^5TtU*|Vum)ib!Wx7%2x}15Ago~p?9Z^67oszW&LBF2=nSGWh|VB7 zgXj#RGlH=z!QNd`V+4(0Yzz0l=j0;6$TLuA{aza+4$F= znZXl*Cjw6do(Mb<)L2735!4ewJrUFsK|K-F6G1%@)DuBH5!4ewJrUFsQ7)_vc_PRY zL7oWmM35(fJQ3uHAWsB&BG5#TCxSc?1eypm(a)oa z4k^jX(h$T5Wv7@3l$&Aa#8!63_(Q_43=`X_|J%r+TpWf=*^hE17;c6l%JpNo-3L*Q zi*f2Zn|SP|jB=6~uHZ1rX<#^ZRg^o2;f|@H+(QgE&lKe{G2CHul&i;ZewHZ5IBR;l z)L5h3S`4?`4(0Y^xHAqYXN2J*olx#3hU+?qaxoZA)CJ{=Fr4Ehla<4F)mKVx>#c)ABC`Ui>@HfV3x`T47 zF`U3%l$&%Tzd4>o0LmF)j+b;FM7e0p@pc5E+y@MIH3a3lFlI`2_V6~l#0{vfF1$_~S|6rsnvi{S)IQ7#q3S$#ygPZ;h+1}{XWNVck9vPRbsf$-%xH8!>w#axy6(5%Tz1se@D4rFkEyS%ALS)Jsl`_8N-Qp zqudh==iG~O?=W0uKgzXWxLHFe$3i>RA`_1lMo?}OhVvXlIVB8NMuYkT3k=6Q6Xm=y zoX({1q>igZ3>U(P9bO*{QV7OLUlrzC_TlSzFEPDp|#`G8lpA2YG z^uuMP(B}#U5ey>ebM@EPCW9vePXwL_JP~*z=(tzBf8?n&Ni++pL4KZU5Qxrt!UlP2 zIZ2`-b%zo{)a5+M^=h0Xan0cRP|e~7^8PI1nvmyGb${Z|7c>!QBG5#ji9i$miB1)k zH=z!O1t8R#wp-DRM=40M-)mDI438s^Sm z?hLxiKzAAFE(6_Vpt}romk})iO$3?`-3I|O$3?8e=?^v5P-6`>)=*;&HP%pL4fRAYcLsSP&_s|Yf;scIyAKpC))Jw+q9$ zenGj@7%u-S%DG~=1q~<{j^U0rqFf$^3us2Ub_`eh9pzZ(O|{6xqfQSK^+JHm!?Pchuxg(#PU;XZSqTq}lK$%S(BSf{t2J`c)m#&FSmD0c|M^(;m? zD-0*T4CQ<=obw8ldye5USD{=bhMTn(yaJ*Yk z?lOkc5k|Qu7%pTh%DuyIEn+Cwg5d-uQI2K7^meh5M!8KG?!`8gQ^IhB9Vlmk;bdh| z&KtwI?nb#p441zb<;pSKg8e8rjNy(dpd8=A>FpPA0Oht}xLPHY)4_1752M^g3}<)* z<$^I>%u$qkgW>v)p1O;5360S}OSEq!lQ$mMb=&%bNcA>*ARDVMCCscnz^(Rz+ zLiHz9e?s*qRDb?Ja^+o+kQkK9K)DQ*%RsrzzB5oR^CyJd&9H`Onbnz z2TXf#l3>~cI;TMA6zH4+r68b*Kofx`0!;*(h~ftz*$Bx-NH#*U5t5CNY=mxdP#z0; zBG5#TCxSc?QE7JuX^ zXd=)=pou^efhGb?1eypm5ojXNL>{J~i9i#9CIU?ang}!zXd=)=povgTbVx~7mWCik zFzjR^P;Nf6=8SJ;XN+$M@$3`ZssESjGb3CXhT}Ivxj_tf!UW}bIHtbh#N$vil#|AA ztrjS!h2geXqud1yXJd4tLaG2E;hD5rqo z6mFrM35N6ZM7duvT$vZj#bG#JUz97sa5{b{*N@>s?xGymqUr6|5`c1&7*6m3%4uLY zt4Anz4#T|&Lb-<+j_?HKGBKR&QqUFDEA7(9mqksuNclN59R22rngJ^dz4#^;rI(tP7cGJC`LI03>R98avm72 z^&`qfW4JAqDE9%w*;J!kH-=03gmUb>)7x)GEy{^vxZQOqr-tF&8c@yw!xc25TmXh+ zZ$Y`2817gr%6-9b_uEl!Cg1dSsp~|!l^AYq56bPqaMQmE?1igS!qq8%V67@#of582 z30J3tt5d?&DdFmraCJ(!Iwf4460S~3o}yE2$S#ruVGY8%?eNB+w}On>L@8h0Zjy&2s9CBBG5#j zi9i#9CIU?anurt(ng}!zXd=)=pou^efhGb?1eypm(J?2`M4*X46M-fIO$3?zg9w_T|Mk`F;EBK!fhPh_1fEFAkB8ikA1=!Pmt}yhVW&-6lHhGhsG5(OShi_s#^?&2O37*QG z#c**0DCdUZ28K{B62nQ4qTG87=R%k>{+6lluM@+)nSpW(_@{o-iN|y3P)-EHDKVg& zDu&BvLpeJPw}2hx?qay3oG6!y;R3i&?h}TqJ5CYJQYkj^PZKpxiDD7qblI zPGh*f6)5M5;Urh1TsVe1zZT{4FkIGplxxRuOads!x`Z(8?SLT431K*|Ehwjg;mU*DjR1)Q?FR)7^Tup$Ol#K4Le&_tk#Kofx`0!;*($jl8i5ojXNM4*X46M-fIO$3?Z)H7+4VlD`H?p46KOxQ&+@5Wn)j+;P}dGk-9?(A?k9Tsa$3l55l*dAO?4RgVM`uV6ev^XJ8Jy03Aa6P`h$yRs zDGNcUtAnXq%;FH({acaZO6etqQo6g$um zPMkbtKsNpO-zZP~hdpM{rW~I5K)1;jpuEKR;iuYzK-e?>dVkh`)Nv;|dBCamri^RK zn@Kr0@#ePu`&| zo9q;*j=@WA;vG}|{_~F44QKxXyY7+Qet=>(Rmy+l8+8<(ob)CWdnbNCl>6f_b>|Ok zw+L?0R6eArw0*a%rr;kqj`D=h{{zpQc*>SP{LG0bl11I09XJl02TlXfCaz;e})DAsBXM7Md#sksQF%g8u$aTh) z+n-S9YH2wkDdos>(3I)u@fq>o*12w@yxb4pCUi98Z|3b4f9J>rlX{lQQQquyx5Y{m zABM`|^tSO7u6p7kUcWhH>J$#A%jYPguWPpOH-{SEp+1G9>hh^{*c6T)bG5L+Nsjt_ zDo3p=z?3&oaoBXoFz1|rGAC~ ze%&3F`lEV$?;%w0;`F%h6b`4y8>VnLJuWi2D37Y|ae7?pI{N-_dfaUahtuN~Q#h*5 zrrMFZUF$aSy41&14)i$HBCrJufCaz;U;(fISm5t!0azRf3rk@YEp;LB-)1G~dqGMd z^6Gw%;`cMNu5QzQd5(sbo|$u#*1x&)iI#Th0Rj#A7Z1<=yIBnuu)_lO-(SG~2Smu< zARp&-`#+eEqan;6pFID)zD--{ruHL4XK4RuKF)SB??lau;qq~Brf|4?9EUraKf~qY zPEFx(`M76OI9xt%rU&}ExO|-Q6por_n>v&qPIA=!R1WfSRExkCEC3b&3xEZ{0$_o^ zs|EfBdVIzG|DYcKmwunK|Jl#;aSiqR{g=Pf8JsaXX)Zq*El`2UEl!V1PvNFM?3mP@ zR1T-d1#V0jh05XdxZxBIr^myla5z2QIEBOM@l`j`_lMKtC#P^!ojuhqk0v?lekuog zoN5u+f(5_=U;(fISO6^WceTLZK#w1c{158!T}pcnkXz?dE*LR!VUF=HmU`8e;mNOg zZ1NfsWNP9@-A+E7HM#x04S8|cKb|?EEEkir^NZW56|$$^SVrtp-m{ZHpuRFye^R&9 zSC~oeSZ_mEOnx}=mzVD+j=?nvP`3@etK)t-w0{?YjyEiqjzC%cHJ`9-x!XR14EZh( z!P`?=g|L!*cM;*0d&*ft1oA&-{j9O1_J-T9JNZxSrXcex1%5?s6q$HrOvI*%4Y zHu)|u!Fv(I2;m#~E)PLt{rP0_9k~5m7Qn@d)Hxa4yZt;F6Hz%_thnjc#1EFr;bKMS zDI6|V%$vgDVnyCx(bvVriUw0ST&(zF3P+6rr`qRQ;>7Dx_ft9QZxo$5qf)R13xEZ{ z0$>5K09XJl@bg>XPp+ljEVx;7hw_0xbXhElvB=N;A)9Ufp=T2aHZ;%f*j`mR%z0(E z;Ju}*4lW|C$o-HdC%>U+e=bqbdPjCuXn~NhdF}?E{pK;JA9%fc7<2lPNX(^}i?7x< z-FWy)WY5*b<-~_i?g!{4hiokH4KTO=e8)Vw#?iTEAkQ}6zS@4n8nI~MT3 zxLx9&)n?{Pk3OZ(Nd0t5NI_PgHRnQ?w$P!MY;@mlY6f_^1mz?yAiEJF16>&hC^dD;^!F7wiTtGS*v zFYc_iv^pWOt!YM_OQxbl_4(skJojcrXxk?)d5}V*SxXWNJ%45sk6S(mtA$Hg$D`4i zqH}+7kmfVmV^F2(_+E-Zoi;6_zj0>N^0UoO9Lzh{@ym>|n}2Ag`^G&Ma^G^JFSj~v zZ3Ac7@pGdpLODKJ?p?YbTVyQG(b0WdSHK$lu%X&)?hE#+Pv2*B^KZ*=c+{(;Iy3T; z{^-H&gRQIjzU!zm<{dO%{fi7Uac{|@z0GQYGwokpne}~H|8vcTSDQ^d)b&b-V`o-< zD!;6-LM@=NK0$uiena>DvAv0F9;EQsYXV|KYkXg^upZVn}wO4Kyk#ea@ zD_I{}E3mt7E9XU(H*+Ih^zL*V%^WU$=*+1mapv9)uT31~rV)(#=l3|r-8FB>>M9*D zbu^Y6zF^fqHap}|PyRqcz1+P(meUerv<01&X05NCH2YoimBJS^)O{L!dd9%-in^x$ za{=W{^VGa&V!I8y-tXMx?slTSt7kcNmm%*)CTbI(?kUyxuyR z!|2k|7LJ`fLw?N8E_x1Zdx+ab?NjZoBF@b*Su~t39LS*Ia%hN?MptizdO)MV173zB zt6b-1rSb6gHNTFYJZJRCjjNuvw5XrCYm2K>)39jV+|Ods8jKxn zYN}CDeV1qC=)DOs7tbw--(@kXoT|&?xA3$Zo$iP7ojK<9Zp+dehE&5|6B)Pynwzzm ziq7jB%BO5q5p78DNVQC@)nLkcVxK!wF+-`(r2lEj=|vLx=AVx;4u0+`DzV;{HL~J< zPi4*WF-Io4TA4KGdx5bJ7WNNw=rftdvBa%3t&Sq}MJHLT<(XrhSyKmN4A@gKVnwu zV2M<#z_XD#10Ad0l)kVl$(yNP5prK}FxB5S(8<31cK^}ymxHtBMl+`*4^$31f8@F7 zvtaS)7Ou!3L1V`+;x;AwXV!KVTx=`5&_)o-A!WG{8|^Ee?^iY~U0xFTiYQ~(T2uGQ znp2`ni&^!>diRB-{0{%I;{5y@&60E;E(`QMx;jp)Hv4ZaJ)f5DSMK*FcI@qKfzvOo z)vT&wt?g<1cv|YXjJgeG)!#|pFzjNbAL;z0s@YU@&i74Y^^0o@2LkE6+CMySt#38n zm$r&avrzi>aei5Dv+|2AY6j-q9xer2M{~y>NRLUXv@aeOH@{)~jIqmrD=RU==iZRG z$=nwlXYWfq_RZh5<9++ES&g4_+-$YJBU^1O$AX@u^?f>g>2eo;w>!W7hA|o4W4D`X z6#5Dxc4c>E4=xEezN)ByR{w=+*RaV(tHQiD*Sa62F(~YLFOX3)cw+wPJ;naQF3-HX zoR=owIxbTbypYAcou5TI|7f7<*vw;Img1L~=117~l#jJ{jhqb6%_7dxt=^;WVV>Gq zKh&_bi(~1~l}Cp1-}pSW_%AB#tf1r1FE7waY5Dl2T6mX_OOLjI&DLKe5)XYa9m`|L zk8uCQ*Snr+uhx$^s9xFW>%GE@}9elO!c?M0rTfhElixg23JXVhd2O3H;x4 zE$Xt#%->7oTc6sK?#Jg?{@1P@U647Ex}>CNDe21bZgo@N|DS#B=!yLEZ?B1WmL4(V zZyxw2O}tsb$%HB{uRJS%f_p=m$06Tv`C{?X2~KwMb#Zy%88s8!#L)-@Do4%lVp{xB zaoBg>P&)9;_leEdwOJ*9eS6~UVtMXs2lol>dO7F7tY)o+ z>o2l?W9cy*npZ|A5kuk-8%!p?r<499Zdlvo8Y}ILT_vF?Ve)3(CbF9f|PiVxQQL)*}3dGY* z7m;*%tTSfhkz68bLU(l6n5{2=H2(`}K-kHFA@DGLp0V0k{%*}NiM0AKr;ju9%;|>T zj!5(He^m_>5z?>ps;wSmtSj?2ue#iE)cKT)SRD_ye_q098_k(o=Ou$#V?CQVRL-Ry zrOnb`hPNG8dK{OgagR0SUno2E{kyB9psI7pwwTfVpUXR%$2wI_2b=l( z7-Y4iHif9$J9>;-f0rR#St4&fJgCQ<$e(mYzd`b2o`S~CfT$4X-4+otb)W8vTh(Or ztvO$Pf2?8G*@~(T?!ZUsYFf;T9@YD`DKnPbi2CNUtES_HlRH8Gy#3V1Vn=u zSD}Ci1VjRIipUj6@+Ty#W@W3@*6QEcr)73`-u-6wo!Rl*H?!ZIk829NmE2Ws>t|Eb zDp7v!;>_2^R(OA5=94&EV-n0sk@?BVsNz8k`~2^3HUOGgP)2R zC0}eh&b~E|jHIAGs`8uMfz{^R9dIW#NBC+1TDm$9B zy5(woa+-Wgw6~pa3(3)Wt>bb#ijg@b5qFMdrWj^KQJ)qxaFy+-wyrh!Xiv$a9m}pg zv+o{A$#J&0VE<6*K~?y(gzGH!-Ui3I*!;d0sT*#wm$HL5Cg3`b_fXO-(e!BVGuJbB zE#6W=tFNQ;YhHIYKdj3SE+*4`< zBNs=F@2uy;fiFK@$;)!PY@~@e+08bCuV}Uf{m`Pi3((QOFKi45@!>kQY&$GJvSZ7Hc`=iRk z3jHg3@75|j5$dShvwqIxqL)wgGlp0soG1N~r>okn_7POz*~u z_~Kg2@?=UAi;^RfJICd8nU$J94Q6jEx^fOnxyP8Ux|p)qXS<_vF+17R+TTx<_Cmav zZB(Ljsj+lnnP`(SZ4`S@iXPBfxY>$HQ=YP(ra_ssEV4VgjObt59Bp~d|CaO(l?Aqr zujjcqW0OU6^+S6o48wCMvxd7FsX~vjarIRlx21#TcSna@XX&t#Fss=&^S4TtU#KJX z>0%2Qos7+9{+rLWW<_B-RJZ21bMB!4lTTpD;TU=S9&OZ(^Oi-swd?4u)g&dw)ubs) zl;fK=JICQ~lM9&P#i8AmjDRN(dPPV{Y#XbBGId7nz+9nx^5JD^1C4$6cHb0^4Uw)# zYedBS*qYYUAahLrbnjS$4n1jG*P3kQ#PQ|(WnZdSIFKVW7H5WdMV{C4S2B@~5$$uQ zm#cJ`;#;5k?kAH^Hf+;SpJZ};sp_fzq`C1;zrR44hjz$l7%1Ox-RUgG!jh{+I};Dt z|7uixL*&U&xrS}nqdIndOv*BE9hQ;%+GRmo>`fXZa(jx?7K?V&w3L?7q?1ZYa131Y zpi235>$;)SW{>JU+Hv)P*DE*IKUXxBK#74 z^44RG2N9W_H4E8``(iZh=*NSCNV~MEPn(!*aQU9FYGE8LQ2OlXt!kG%tzNn|@4L=8 znK#QsI)W<3%&%NpO_@kP=c842XRFDmbgLN`uI-k~mROn^hmx?Gx_}gycGRaOUb`o5 zf2@7Ap?Y6lZgmfqF-K$XV0?4-#L|QEPD8iwmLj=01~qE#1@?Y_8D_+5qP|mU-?lVW zX?JV+#Qj6%)7gjEU74X+21RF2WWBfvrpHS1#Pacy!KGn`dW=SEt1h3}tC{0#Dyo=k z_e01|xzQBO4w<|2nJIBac@}<6S?JSN5^^C5#l)2_UBVXNdmfh`QnPcS z!h&#eM6vA(w$3d&E_r<}NiX7LUn=4YXqCICi%@SUC6Ds^b+>ZVkM3%BE3{OeTHMJQ zx;=`n@9&pTmz8^@>UxtTEuNVCV_j7>(dR|{OYb?%*38cBStW8Y`=}Ss?+#)(#Jd&zG1UGGrnsI(|K&WX9?UejgY6gGv< z&<=I(*m$o}I^>j9c8R)iU`8&3P;Gg5d|@~xggj+Yp=GuPsk?Mf5~*cehL%}mx?gl{ zc6m&nd~*6DtFg!KcxJk$ZPStL2sl(6HKx4SDeJg2v%lkM+ez7q@G$3y>;cu5U^}($ zG7~wPM4be+J)(Gwevk9$-f}NyLu@iBEUoM2cZGqGVNWN9O=k3jX_3l^b57|L)?}A- zZ&(;3Z8@)lAy%XDGdl{$`AOFI*^`HUwI==RgX=}97t0PgSN7!8F2NGZ3OdxwFG%Ee z8y#eAX}e{OlMRbcOTy4{m9*j$afR$@q0Z6R`zeIhl60!+p|At2fmm0ay9YIE2Z;F= z?8>SV!rna^h4f;V)Y^-WNz->XZ6~z5b~*>x+6&S2;==b^$`euBpGrxx*3lH^i>%k2 zYr~=!J*mtpY9ZjWT8ngxN$b*{h4rc(!TO%$D8&9g}iI&FzT z<7=IJ90G?tSS=v~gvLFZQTpAvjG@iDoZ6<85m|KW-K>@rbj7v7^8@K~x5RYOBU&BB zO^O~rT4$vcMi?Izr>ePYa}aB+)0$LOiNejQFHX9!=BFgmSjv+w&Y>pA4f^_Zx<9`Rum7-^-y5=<9w-Y$`ilVO)i=8LLnEiaTSl;iB1`C8~SKiKBYV zjTh%A^(^&`mvx!9k)j<>P}Wr4mX(!b7o{Kj!rbyQgLSDj(9eWY9_!?%!Ra2VQwuHG zS!CNl7PjvXqMzy29yV%0Yyw4WaclbENwP+tKC|!kvs-ib-5A?5al4)WdQ?xi-qQY< z;$GLTo&7RT)U9r}&VEi=CO*JM_0{e*RO==9L|wbCz;X_;l`jiemJ-Yv=gzH@nt0St ztAQPKsN}Z^W~J46zJ~`J+^gLQIPsazQU(Kz!lli$`^;G1WhW*dUbk71QAk_R8aJ-m z80X1qnYbM%RqdEWXi>CluvQc=x^8igecoSo5#7k&w}x;js2iuGUb7Rs7;kr`q_14r zy?GVgqNUMXa+_tOE-8AjT&*I?=TvJ2b9Rp@J)RM%M_SOCNcK#b>iMejg=)pgp8NsD zry?&Gmd801E61+(H4xrStza~Cj_(O(*QkaQjJ;-UBq{7B-SL`VeRVk#%T6MajYVG) z4cD~pEjbWlZOJ%GV7~Sn%F;DtlxZvLGgDL(mv&GVTPt#gz;n_U7@W@N|A*E3j-c#f zp$=rmWUj}23I)AOBN+FMT6q$&rI%q@++Z!wEo zifdNwDJy6xs&`j+k^a$Pyqsq)dF|1nGL;P{o{ zo0Qhv#jamqrL;W^dsMXHyLG-UIilgE!RpkRv(yzt#|Cf27SfCh*U!~?O|Q;6ES>zk zb6K7R+mx7;QDM>KarelrTTI=b6(&_mP0RCKv|wW5sO&o7WXkC40ihmt57#}Zynj=Y zRq(`HR^Qm*_k6F#UQ_eTp7b%6?eFZ*Z8B?>*Xvue%R*jD6QCcVE~ z(I75ODJms0=LWiEWAje-&t7{1(*7`9h97N@mK|(lk6Rm(@6{5Wk<;{p@GDXgGt_s( zujbM;Z(Row`~q!}jRO~iav9=%ud1t}*10Lm8@uP5FCDKWOun!GlXW4cda+2Xu&za% z>x3u_HOOdoGdPL*E0Z()R6QP0JKnWQc5zSEAdABo@c z-nI1c1#PcHyI09*s?{WWp^a>(0Je$Oguw2=A``SZh1%D!#9&KQw@hDE{c2Wb7{20U zS1~TmxVXUm(NK&~1nUK+T$D4+<8{!MAjCsH4TnRkJ+wguaTvO zl4r52bBAobu47N1?7&w!vCK%dNx!7{-eMjeJlmtz7}09%-^za4D84z?k>ct>G8!P9 zNmpGoc7;!(ndV@UbX9xRZw5t}F?AWU+H3xJJ$G*Hk(yKsiljCgZ=E7{TwW$>dPD#* zAiKL&SN;}0VW88~{&YyUUQ1CYy^5)&*^%fqCZ4*Hl;xjPQ2u*l&Z?I~g{6**2E~&y zUBX4F<#rRMI!>Brbge=uqv$v7wW8!HOUL^bE4-H8*R;Z_Xd2tcJUaI#F7%aILn97- z)6TTX+^jT*TsOMI@VVQu@RXh$zk3ST#zq;11lUb}-u#fDoNh7A-~GNJ;3U-dD{a%^VW7@hum{w^=y& z72|sKWli_K3Vi7ydLbwip9YbC13 zPckH`Xy6((JKNJAmulDDh)8(6&uYOEb*#myqnVT_wvlbqO398F$yeJ~9y#uM`+nx& zfx#2lVxy`Q(yp1&X6+8s#UIU^>NDB~V;_{rz{`!rWP7duukj#i&ESWX%=>wcl0Oq1jABiXOm_RybXj0;_bd02jG zOPf|_0jWaoA-i?T^X9{&a6t!L7*h1A&5L$R)>F<~_m97pbG4?t`6qUtXxv%m(*T-D z2JS(Il1cn|H`FLxfJN%~o1*=(?K+8Z0YwK6cK%*2j~`f&sy(>w;*2L_CJ)YFc55{d zb87E)vDG51FAVJ3wN=&EXx*TXEJwt-MSgBHNI2?`B`2pWGjJv)f zzTkv@aw98&uqR;QYmo|z@UeD`o+n-=;l6Ak^qz4uzT#OJ@pRq@LroH03F65&FX+6#tef-_#>3V zyLkwQG^;}whC`awL3=4^51Oq3FIu?^%<6!10*(O#fC0b&U;r=x7yt}>2?qYnj~h5; z|BjVKp(OWe49)g2-8O3qM&xGV=_OVHXc4)O_~V5U?cbC>`2T9=zq*bF=o9eH|87U; zyf#VZrK&VUT$CA<+#ewmTK(fJY4`<54^M3l%Dqg?arlY(zcmC_GXblae0Vhz&NJ}e z=_tsa#8<4#bq??(qA#k;A?av_$P^CenDO;22#2Jj{R+b&>1Z!tI3yiS;}y`+KF~BE z8!!ME01N;I00V#lz`#Gkz*p=?llY4Xeo;SKh9AH=UxxQv^(q+aP`{dT^ov@OAnXzjKGZ|!1@=gc+@+|9d!*J?=qIHY?cwJm|~7ehEC zfBZTOhvbhlVK^jze8p?vk0Z4SI1d;A3;+fI1Aqa*0AS#sWZ*0I$K&`C^uOYd8}mOt zgX`mO{c)M?)_BKv9r6bU-f_s0{PEQvXv{-=zZk+H`Qv3U9Fjk-+{5#;A$v&vxGf(C zRS&{}Xuc35AO#En1^@$q0l)xY05I^+F!1^QxZLoP6|!nL6mLNYUDSLD)ON9wLE_b10 z?p4FZyuUhzE*JjUn-ITTr1f>)`r~75tsR^^IYAlT24s*u^Ts3R`Qu{mt`SVdv5wBA~nIHuW00sa9fC0b&U;r@i4KeTy_~U`vU(g>n_-WM!lqjbGh4>T6 zhuacb^YRM6W!2~N9d9B22`J?sO7hbWC7d^mH&^mJOYYl>S_kCTvl6`;m;bzK1xlEU zli--!F(Z&)wj>HFMKb-;I)hCd6bh;zRF6@p4Ja>^8t0IgQ&r3>Nr4Z5Qpe}Q z_m}^?)&M2^%fKvQlnEzW4W)dwKo~Wivnz|5@_pEksH2=+B~%n@^CpxIXLl0nMC7I| z9P=oYJc@Pi;SSWaVeFmo?42k!XIBMPh>;3F)erB=E(tw?qH=Z>Q5$XqpFkyXcI8n% zjfdM%%AC3>qfW?+GEs{-yGkgWi;FTR8*E>cflqy-oZc_^CWiDzxf_Nncj9A zj<_L)(QrtJTH!l3RnNQk)5gCijuxZeJ|$nHxli^uz5zw~!D^lq!I>>)NHa46U^pZltq6ug($Q2_2$qYaqdCKHkUj?Qh`0GT z=sbi2IvT_XNC5+Y0l)xY05AX;_*NPC2K;E*&0m2Zz3~GLEU}VTNeGAJN1MZNNPct@ z42R@LvtT$RKibGZuzpB>^jR1V$&c=W;UNDQPSbKjUb)bD2nYOVh!Kzi1^@$q0l)xY z05I^aGVl%f(WX{kfgcU&%t-AV$@do_9FiaX42DDUqp_=aHx1cC@}rOL6vQF<(RDB! zk{_+^C}r?>IWLXihhoJa(J&xYm%N8oC0tN4N&njcXO%@6q|!Y>9& zF{rv>`~=SAU+&H>YiFB}smVAFNSE_Jo)b3Cj^O4EUBf;1XB%`K-`}!zBRCJk1ODtH zP9E$!4+0;b^O4uRiG(M_i-h+k!W~-4iQgg+CBqiqjc}J{f7;?>b#utbhRM8&LB|+Q z01a-F$Z-DWQjJ2X4gY;puTPKAca+GxfvKFJ7~JB9&BN=@=@G-_{at@}^SEW+8~?Zg zFaB(M5Xh@6gyU9vq)jhK5Qn6%XTopR~wOcLF%tG*r;uY&AH7cU;29LAekP>JGeT4$1{7U;r=x7yt|a1^@$Jk^#=k`XAUa zC^Z>O&a?3(f)rZUBu6MSurdGA(peAeJ6l_~bR5llu}|r_i{d$H##!mkxXkWUi7d{4 zZ$CeM=S$QN?vfU1p#8&w8K7LiGw4^~Ir`Yh2w>a*<1_g8=1YRFI3yhneL~P4l8)vL!y)NtT`(Myj^=Puuv{b^tsaI$ z($P$#1nnW|XeBTll8(0el%PE%9W57zL(OuI(f;w3V<*M(B!{t_d2d|#;Jvt_+StlkFW`biCpT)-rMlMDjnK>z^OfUn^#E)ha?>` zU^pb{&?;Nd9+GrOh2fB-!ym|k_K>8*Utl;S>98M$Ly`_HD1zl8Nr!h~I3($CR*s-O zBoU>7zV>3Nr$gsI3(%NNSj?z?oJaz^ObuJno0?2Pr(R?guV}u6q-P z_Py}9sU+Y;P} z)^0oS)-Kj~2M=$VLSA)wC4I%bHaGkWync8bfOwVJZjE<*msop#*BvI-VAH0RDE3v} z#|P*kPOsqh_Lfnijl((W^Lh7%zJfw+;pXhuy79~Kh2Q9(PhE=uy4}xS69F>xiK*r% zUI$(Fx%L0t^0^aQu-uMx=Pc`T6G0?Y_Y)UI$jOnGyhk?N4-5hh|H`5opxb~)@2@Yx z@{f%+(6|iJFT()ub6m0aKF8hof#Nkvd5#c-Lkd?H2*V+Tq5B<%Lkcf9rA)9~q_A-w zFdR}ixO*@hQkb_1e+ZU~6u!-lkAvugaM1hA@Jj}i2~xlSU;r=x7yt|a1^@%!5Cfm; zH{OK#QAmE{=yE}S3(0TX3d14!jaOkfB)@S8hC}ij*HsAC56N$gh2bE75Z=_Cd>nKh z!U4Y#Vg#gs0l)xY05AX;01SMq3>d6hu^dIz5X@mE0AnbzjY5h>X6yDz2 z&CUkOm_CYE2Q*4{hl9Id-VJFePs(POjhme}bdjMVlp({r!p7Ft0qvm-e)mWJ3}wo4&RaXU zy_2`vl9%`G^oHT~cjo`T&aHOxnFaoD+FyAULTl|?4Q0IFS~Y8+JXmXKt%Wk)Yb_fO oC~KtFN+P|<9ig?BMnbtGv{peZl=*&ZZM(wD`*vFE@2~0q045Eg4gdfE literal 0 HcmV?d00001 diff --git a/src/PRAS/PRASBase/toymodel.pras b/src/PRAS/PRASBase/toymodel.pras new file mode 100644 index 0000000000000000000000000000000000000000..c7d0fdef50b47a20fa0615e3674c7a28cbd284a2 GIT binary patch literal 17368 zcmeHOeM}rh6ra6=y94gvpi0hC>Cx1Lq=I`bAZz28I_j?i90hYXnE zKn_6n97Jv>{+&iF7$$~wHC0teLj6-p%ozEfBjBy7Jb)mmCpcIL9Vg?ATqj&^O}<@~N z3r3Vi9?;or=UwF`{EiY=Ssl+ms{CwI&Wan@{!ZdA2lB9=*pnD(^o83)GO)u3fuDs( z4Z}&}ftH%RJiA&u zj)pbkRw9sS-tmz6fLhQYPv-|JPn82@Z^CsBm_lBk{%nNh6nynC-E5!2F0a?v}feJ8Q2NZ(vCbb ziy-BhJ*OJ9nO@Vmom{H;*5~0U@T{msRM#dtYs6MG@uzfjaHlT~+F~Ai`sDk+8IBD^ z%3^2J?koDDsW@h`554!&<-F<&_g^iiN^+k${_;0-*KD7>F~9Yzg|WTiz{1$$;r{u+ z(Q9wHv%9Xm=`QTL^0s^9xnCv=+~dakt|?=ntigJ?iz{j=zJOpW2-n<3ZYF?1b~!=@ZlSL&cM0 zqu+m4eUpEz|NIvIJKsb0TFY$5Q+e$dUz_sHJy^J}?`KC>&xMI?6+I0zt_4%ypzZaE zrs3MMC$2a26wbKhoW8-`9oFFV@t*t}j!(NUOx$15^TDi3&gdK5arOBR7hhPajhr;x zaC{qir*t%9Hf!;B7{&x=gLs@D`19#tjybp3>foD3Vw};m3UkwHEr63CG`i%1Mi%2o zyGB1R*lLed)||Q3eE8$3_M%&rn}6swZkhq+og-X!B({?6zM5^FeRuKe)W;sPWC$<> z?nMM>y+M;Qj?{S^PJe(?$%3>}E&kdF*F}&DEE?e&3_6_3S0)i|m_mH8QZyAiQkd(yqcaII}Q`gFYR19EEOejZh69NBI`gL zNJGhpHM_(Gn(b2hT#}%ANmfbKP-oFW2*DJ~*qI@~5MT%}1Q-Gg0fqoWVErS& z0h^NR#jp3zIC0&Ve*TnA#0 zy8D@}Xb(`3!%}p76K#)!EAA*J3kfWKeV=T%1C0(S`uR{W0`30o`o0eqo2_A~leX`n zOae;x1#sU0h$YaYVyds!zbp0;ex>^e%XWbEb?q$NN1*#6<7C-1zRFFskK);aBk|CH z2>qvZKE>Hdo(H|YgLQt4gp8U*&8?{O5gvf-565*YvFa#I^3;~7!Ltq^uunzL^ z0kTB>pXB4}x;Op)ZG8C#l9rF>!c<)FOS*L2tNY`EMEQ7ik}>il%g2)-#BMVL7y=9d Ph5$o=A;1v0w-ERnd*u|z literal 0 HcmV?d00001 diff --git a/src/PRAS/PRASBase/units.jl b/src/PRAS/PRASBase/units.jl new file mode 100644 index 0000000..1b7bd8f --- /dev/null +++ b/src/PRAS/PRASBase/units.jl @@ -0,0 +1,116 @@ +# Augment time units + +unitsymbol(T::Type{<:Period}) = string(T) +unitsymbol(::Type{Minute}) = "min" +unitsymbol(::Type{Hour}) = "h" +unitsymbol(::Type{Day}) = "d" +unitsymbol(::Type{Year}) = "y" + +conversionfactor(F::Type{<:Period}, T::Type{<:Period}) = + conversionfactor(F, Hour) * conversionfactor(Hour, T) + +conversionfactor(::Type{Minute}, ::Type{Hour}) = 1 / 60 +conversionfactor(::Type{Hour}, ::Type{Minute}) = 60 + +conversionfactor(::Type{Hour}, ::Type{Hour}) = 1 + +conversionfactor(::Type{Hour}, ::Type{Day}) = 1 / 24 +conversionfactor(::Type{Day}, ::Type{Hour}) = 24 + +timeunits = Dict( + unitsymbol(T) => T + for T in [Minute, Hour, Day, Year]) + +# Define power units + +abstract type PowerUnit end +struct kW <: PowerUnit end +struct MW <: PowerUnit end +struct GW <: PowerUnit end +struct TW <: PowerUnit end + +unitsymbol(T::Type{<:PowerUnit}) = string(T) +unitsymbol(::Type{kW}) = "kW" +unitsymbol(::Type{MW}) = "MW" +unitsymbol(::Type{GW}) = "GW" +unitsymbol(::Type{TW}) = "TW" + +conversionfactor(F::Type{<:PowerUnit}, T::Type{<:PowerUnit}) = + conversionfactor(F, MW) * conversionfactor(MW, T) + +conversionfactor(::Type{kW}, ::Type{MW}) = 1 / 1000 +conversionfactor(::Type{MW}, ::Type{kW}) = 1000 + +conversionfactor(::Type{MW}, ::Type{MW}) = 1 + +conversionfactor(::Type{MW}, ::Type{GW}) = 1 / 1000 +conversionfactor(::Type{GW}, ::Type{MW}) = 1000 + +conversionfactor(::Type{MW}, ::Type{TW}) = 1 / 1_000_000 +conversionfactor(::Type{TW}, ::Type{MW}) = 1_000_000 + +powerunits = Dict( + unitsymbol(T) => T + for T in [kW, MW, GW, TW]) + +# Define energy units + +abstract type EnergyUnit end +struct kWh <: EnergyUnit end +struct MWh <: EnergyUnit end +struct GWh <: EnergyUnit end +struct TWh <: EnergyUnit end + +unitsymbol(T::Type{<:EnergyUnit}) = string(T) +unitsymbol(::Type{kWh}) = "kWh" +unitsymbol(::Type{MWh}) = "MWh" +unitsymbol(::Type{GWh}) = "GWh" +unitsymbol(::Type{TWh}) = "TWh" + +subunits(::Type{kWh}) = (kW, Hour) +subunits(::Type{MWh}) = (MW, Hour) +subunits(::Type{GWh}) = (GW, Hour) +subunits(::Type{TWh}) = (TW, Hour) + +energyunits = Dict( + unitsymbol(T) => T + for T in [kWh, MWh, GWh, TWh]) + +function conversionfactor(F::Type{<:EnergyUnit}, T::Type{<:EnergyUnit}) + + from_power, from_time = subunits(F) + to_power, to_time = subunits(T) + + powerconversion = conversionfactor(from_power, to_power) + timeconversion = conversionfactor(from_time, to_time) + + return powerconversion * timeconversion + +end + +function conversionfactor( + L::Int, T::Type{<:Period}, P::Type{<:PowerUnit}, E::Type{<:EnergyUnit}) + to_power, to_time = subunits(E) + powerconversion = conversionfactor(P, to_power) + timeconversion = conversionfactor(T, to_time) + return powerconversion * timeconversion * L +end + +function conversionfactor( + L::Int, T::Type{<:Period}, E::Type{<:EnergyUnit}, P::Type{<:PowerUnit}) + from_power, from_time = subunits(E) + powerconversion = conversionfactor(from_power, P) + timeconversion = conversionfactor(from_time, T) + return powerconversion * timeconversion / L +end + +powertoenergy( + p::Real, P::Type{<:PowerUnit}, + L::Real, T::Type{<:Period}, + E::Type{<:EnergyUnit}) = p*conversionfactor(L, T, P, E) + +energytopower( + e::Real, E::Type{<:EnergyUnit}, + L::Real, T::Type{<:Period}, + P::Type{<:PowerUnit}) = e*conversionfactor(L, T, E, P) + diff --git a/src/PRAS/PRASBase/utils.jl b/src/PRAS/PRASBase/utils.jl new file mode 100644 index 0000000..a4f324b --- /dev/null +++ b/src/PRAS/PRASBase/utils.jl @@ -0,0 +1,30 @@ +function makeidxlist(collectionidxs::Vector{Int}, n_collections::Int) + + n_assets = length(collectionidxs) + + idxlist = Vector{UnitRange{Int}}(undef, n_collections) + active_collection = 1 + start_idx = 1 + a = 1 + + while a <= n_assets + if collectionidxs[a] > active_collection + idxlist[active_collection] = start_idx:(a-1) + active_collection += 1 + start_idx = a + else + a += 1 + end + end + + idxlist[active_collection] = start_idx:n_assets + active_collection += 1 + + while active_collection <= n_collections + idxlist[active_collection] = (n_assets+1):n_assets + active_collection += 1 + end + + return idxlist + +end diff --git a/src/PRAS/PRASBase/write.jl b/src/PRAS/PRASBase/write.jl new file mode 100644 index 0000000..c1ec757 --- /dev/null +++ b/src/PRAS/PRASBase/write.jl @@ -0,0 +1,318 @@ +""" +savemodel(sys::SystemModel, outfile::String) -> nothing + +Export a PRAS SystemModel `sys` as a .pras file, saved to `outfile` +""" +function savemodel( + sys::SystemModel, outfile::String; + string_length::Int=64, compression_level::Int=1, verbose::Bool=false) + + verbose && + @info "The PRAS system being exported is of type $(typeof(sys))" + + h5open(outfile, "w") do f::File + + verbose && @info "Processing metadata for .pras file ..." + process_metadata!(f, sys) + + verbose && @info "Processing Regions for .pras file ..." + process_regions!(f, sys, string_length, compression_level) + + if verbose + @info "The PRAS System being exported is a " * + (length(sys.regions) == 1 ? "single-node" : "zonal") * + " model." + end + + if length(sys.generators) > 0 + verbose && @info "Processing Generators for .pras file ..." + process_generators!(f, sys, string_length, compression_level) + end + + if length(sys.storages) > 0 + verbose && @info "Processing Storages for .pras file ..." + process_storages!(f, sys, string_length, compression_level) + end + + if length(sys.generatorstorages) > 0 + verbose && @info "Processing GeneratorStorages for .pras file ..." + process_generatorstorages!(f, sys, string_length, compression_level) + end + + if length(sys.regions) > 1 + verbose && @info "Processing Lines and Interfaces for .pras file ..." + process_lines_interfaces!(f, sys, string_length, compression_level) + end + + end + + verbose && @info "Successfully exported the PRAS SystemModel to " * + ".pras file " * outfile + + return + +end + +function process_metadata!( + f::File, sys::SystemModel{N,L,T,P,E}) where {N,L,T,P,E} + + attrs = attributes(f) + + attrs["timestep_count"] = N + attrs["timestep_length"] = L + attrs["timestep_unit"] = unitsymbol(T) + attrs["power_unit"] = unitsymbol(P) + attrs["energy_unit"] = unitsymbol(E) + + attrs["start_timestamp"] = string(sys.timestamps.start); + attrs["pras_dataversion"] = PRAS_VERSION + + return + +end + +function process_regions!( + f::File, sys::SystemModel, strlen::Int, compression::Int) + + n_regions = length(sys.regions.names) + + regions = create_group(f, "regions") + regions_core = reshape(sys.regions.names, :, 1) + regions_core_colnames = ["name"] + + string_table!(regions, "_core", regions_core_colnames, regions_core, strlen) + + regions["load", deflate = compression] = sys.regions.load + + return + +end + +function process_generators!( + f::File, sys::SystemModel, strlen::Int, compression::Int) + + generators = create_group(f, "generators") + + gens_core = Matrix{String}(undef, length(sys.generators), 3) + gens_core_colnames = ["name", "category", "region"] + + gens_core[:, 1] = sys.generators.names + gens_core[:, 2] = sys.generators.categories + gens_core[:, 3] = regionnames( + length(sys.generators), sys.regions.names, sys.region_gen_idxs) + + string_table!(generators, "_core", gens_core_colnames, gens_core, strlen) + + generators["capacity", deflate = compression] = sys.generators.capacity + + generators["failureprobability", deflate = compression] = sys.generators.λ + + generators["repairprobability", deflate = compression] = sys.generators.μ + + return + +end + +function process_storages!( + f::File, sys::SystemModel, strlen::Int, compression::Int) + + storages = create_group(f, "storages") + + stors_core = Matrix{String}(undef, length(sys.storages), 3) + stors_core_colnames = ["name", "category", "region"] + + stors_core[:, 1] = sys.storages.names + stors_core[:, 2] = sys.storages.categories + stors_core[:, 3] = regionnames( + length(sys.storages), sys.regions.names, sys.region_stor_idxs) + + string_table!(storages, "_core", stors_core_colnames, stors_core, strlen) + + storages["chargecapacity", deflate = compression] = + sys.storages.charge_capacity + + storages["dischargecapacity", deflate = compression] = + sys.storages.discharge_capacity + + storages["energycapacity", deflate = compression] = + sys.storages.energy_capacity + + storages["chargeefficiency", deflate = compression] = + sys.storages.charge_efficiency + + storages["dischargeefficiency", deflate = compression] = + sys.storages.discharge_efficiency + + storages["carryoverefficiency", deflate = compression] = + sys.storages.carryover_efficiency + + storages["failureprobability", deflate = compression] = sys.storages.λ + + storages["repairprobability", deflate = compression] = sys.storages.μ + + return + +end + +function process_generatorstorages!( + f::File, sys::SystemModel, strlen::Int, compression::Int) + + generatorstorages = create_group(f, "generatorstorages") + + genstors_core = Matrix{String}(undef, length(sys.generatorstorages), 3) + genstors_core_colnames = ["name", "category", "region"] + + genstors_core[:, 1] = sys.generatorstorages.names + genstors_core[:, 2] = sys.generatorstorages.categories + genstors_core[:, 3] = regionnames( + length(sys.generatorstorages), sys.regions.names, sys.region_genstor_idxs) + + string_table!(generatorstorages, "_core", + genstors_core_colnames, genstors_core, strlen) + + generatorstorages["inflow", deflate = compression] = + sys.generatorstorages.inflow + + generatorstorages["gridwithdrawalcapacity", deflate = compression] = + sys.generatorstorages.gridwithdrawal_capacity + + generatorstorages["gridinjectioncapacity", deflate = compression] = + sys.generatorstorages.gridinjection_capacity + + generatorstorages["chargecapacity", deflate = compression] = + sys.generatorstorages.charge_capacity + + generatorstorages["dischargecapacity", deflate = compression] = + sys.generatorstorages.discharge_capacity + + generatorstorages["energycapacity", deflate = compression] = + sys.generatorstorages.energy_capacity + + generatorstorages["chargeefficiency", deflate = compression] = + sys.generatorstorages.charge_efficiency + + generatorstorages["dischargeefficiency", deflate = compression] = + sys.generatorstorages.discharge_efficiency + + generatorstorages["carryoverefficiency", deflate = compression] = + sys.generatorstorages.carryover_efficiency + + generatorstorages["failureprobability", deflate = compression] = + sys.generatorstorages.λ + + generatorstorages["repairprobability", deflate = compression] = + sys.generatorstorages.μ + + return + +end + +function process_lines_interfaces!( + f::File, sys::SystemModel, strlen::Int, compression::Int) + + lines = create_group(f, "lines") + + lines_core = Matrix{String}(undef, length(sys.lines), 4) + lines_core_colnames = ["name", "category", "region_from", "region_to"] + + lines_core[:, 1] = sys.lines.names + lines_core[:, 2] = sys.lines.categories + for (lines, r_from, r_to) in zip(sys.interface_line_idxs, + sys.interfaces.regions_from, + sys.interfaces.regions_to) + lines_core[lines, 3] .= sys.regions.names[r_from] + lines_core[lines, 4] .= sys.regions.names[r_to] + end + + string_table!(lines, "_core", lines_core_colnames, lines_core, strlen) + + lines["forwardcapacity", deflate = compression] = + sys.lines.forward_capacity + + lines["backwardcapacity", deflate = compression] = + sys.lines.backward_capacity + + lines["failureprobability", deflate = compression] = sys.lines.λ + + lines["repairprobability", deflate = compression] = sys.lines.μ + + + interfaces = create_group(f, "interfaces") + + ints_core = Matrix{String}(undef, length(sys.interfaces), 2) + ints_core_colnames = ["region_from", "region_to"] + + ints_core[:, 1] = + getindex.(Ref(sys.regions.names), sys.interfaces.regions_from) + ints_core[:, 2] = + getindex.(Ref(sys.regions.names), sys.interfaces.regions_to) + string_table!(interfaces, "_core", ints_core_colnames, ints_core, strlen) + + interfaces["forwardcapacity", deflate = compression] = + sys.interfaces.limit_forward + + interfaces["backwardcapacity", deflate = compression] = + sys.interfaces.limit_backward + + return + +end + +function regionnames( + n_units::Int, regions::Vector{String}, unit_idxs::Vector{UnitRange{Int}}) + + result = Vector{String}(undef, n_units) + for (r, units) in enumerate(unit_idxs) + result[units] .= regions[r] + end + + return result + +end + +function string_table!( + f::Group, tablename::String, colnames::Vector{String}, + data::Matrix{String}, strlen::Int +) + + nrows, ncols = size(data) + + length(colnames) == ncols || + error("Number of column names does not match provided data") + + allunique(colnames) || + error("All column names must be unique") + + all(x -> x <= strlen, length.(data)) || + error("Input data exceeds the specified HDF5 string length") + + stringtype_id = h5t_copy(hdf5_type_id(String)) + h5t_set_size(stringtype_id, strlen) + stringtype = Datatype(stringtype_id) + + dt_id = h5t_create(H5T_COMPOUND, ncols * strlen) + for (i, colname) in enumerate(colnames) + h5t_insert(dt_id, colname, (i-1)*strlen, stringtype) + end + + rawdata = UInt8.(vcat(vec(convertstring.(permutedims(data), strlen))...)) + + dset = create_dataset(f, tablename, Datatype(dt_id), + dataspace((nrows,))) + h5d_write( + dset, dt_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, rawdata) + +end + +function convertstring(s::AbstractString, strlen::Int) + + oldstring = ascii(s) + newstring = fill('\0', strlen) + + for i in 1:min(strlen, length(s)) + newstring[i] = oldstring[i] + end + + return newstring + +end diff --git a/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl b/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl new file mode 100644 index 0000000..05a7873 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl @@ -0,0 +1,60 @@ +@reexport module ResourceAdequacy + +using MinCostFlows +using ..PRASBase + +import Base: -, broadcastable, getindex, merge! +import Base.Threads: nthreads, @spawn +import Dates: DateTime, Period +import Decimals: Decimal, decimal +import Distributions: DiscreteNonParametric, probs, support +import OnlineStatsBase: EqualWeight, fit!, Mean, value, Variance +import OnlineStats: Series +import Printf: @sprintf +import Random: AbstractRNG, rand, seed! +import Random123: Philox4x +import StatsBase: mean, std, stderror +import TimeZones: ZonedDateTime, @tz_str + +export + + assess, + + # Metrics + ReliabilityMetric, LOLE, EUE, + val, stderror, + + # Simulation specifications + Convolution, SequentialMonteCarlo, + + # Result specifications + Shortfall, ShortfallSamples, Surplus, SurplusSamples, + Flow, FlowSamples, Utilization, UtilizationSamples, + StorageEnergy, StorageEnergySamples, + GeneratorStorageEnergy, GeneratorStorageEnergySamples, + GeneratorAvailability, StorageAvailability, + GeneratorStorageAvailability, LineAvailability, + + # Convenience re-exports + ZonedDateTime, @tz_str + +abstract type ReliabilityMetric end +abstract type SimulationSpec end +abstract type ResultSpec end +abstract type ResultAccumulator{S<:SimulationSpec,R<:ResultSpec} end +abstract type Result{ + N, # Number of timesteps simulated + L, # Length of each simulation timestep + T <: Period, # Units of each simulation timestep +} end + +MeanVariance = Series{ + Number, Tuple{Mean{Float64, EqualWeight}, + Variance{Float64, Float64, EqualWeight}}} + +include("metrics.jl") +include("results/results.jl") +include("simulations/simulations.jl") +include("utils.jl") + +end diff --git a/src/PRAS/ResourceAdequacy/metrics.jl b/src/PRAS/ResourceAdequacy/metrics.jl new file mode 100644 index 0000000..fc8aa6b --- /dev/null +++ b/src/PRAS/ResourceAdequacy/metrics.jl @@ -0,0 +1,114 @@ +struct MeanEstimate + + estimate::Float64 + standarderror::Float64 + + function MeanEstimate(est::Real, stderr::Real) + + stderr >= 0 || throw(DomainError(stderr, + "Standard error of the estimate should be non-negative")) + + new(convert(Float64, est), convert(Float64, stderr)) + + end + +end + +MeanEstimate(x::Real) = MeanEstimate(x, 0) +MeanEstimate(x::Real, ::Real, ::Nothing) = MeanEstimate(x, 0) +MeanEstimate(mu::Real, sigma::Real, n::Int) = MeanEstimate(mu, sigma / sqrt(n)) + +function MeanEstimate(xs::AbstractArray{<:Real}) + est = mean(xs) + return MeanEstimate(est, std(xs, mean=est), length(xs)) +end + +val(est::MeanEstimate) = est.estimate +stderror(est::MeanEstimate) = est.standarderror + +Base.isapprox(x::MeanEstimate, y::MeanEstimate) = + isapprox(x.estimate, y.estimate) && + isapprox(x.standarderror, y.standarderror) + +function Base.show(io::IO, x::MeanEstimate) + v, s = stringprecision(x) + print(io, v, x.standarderror > 0 ? "±"*s : "") +end + +function stringprecision(x::MeanEstimate) + + if iszero(x.standarderror) + + v_rounded = @sprintf "%0.5f" x.estimate + s_rounded = "0" + + else + + stderr_round = round(x.standarderror, sigdigits=1) + + digits = floor(Int, log(10, stderr_round)) + + rounded = round(x.estimate, digits=-digits) + reduced = round(Int, rounded / 10. ^ digits) + v_rounded = string(Decimal(Int(x.estimate < 0), abs(reduced), digits)) + + s_rounded = string(decimal(stderr_round)) + + end + + return v_rounded, s_rounded + +end + +Base.isapprox(x::ReliabilityMetric, y::ReliabilityMetric) = + isapprox(val(x), val(y)) && isapprox(stderror(x), stderror(y)) + +# Loss-of-Load Expectation + +struct LOLE{N,L,T<:Period} <: ReliabilityMetric + + lole::MeanEstimate + + function LOLE{N,L,T}(lole::MeanEstimate) where {N,L,T<:Period} + val(lole) >= 0 || throw(DomainError(val, + "$val is not a valid expected count of event-periods")) + new{N,L,T}(lole) + end + +end + +val(x::LOLE) = val(x.lole) +stderror(x::LOLE) = stderror(x.lole) + +function Base.show(io::IO, x::LOLE{N,L,T}) where {N,L,T} + + t_symbol = unitsymbol(T) + print(io, "LOLE = ", x.lole, " event-", + L == 1 ? t_symbol : "(" * string(L) * t_symbol * ")", "/", + N*L == 1 ? "" : N*L, t_symbol) + +end + +# Expected Unserved Energy + +struct EUE{N,L,T<:Period,E<:EnergyUnit} <: ReliabilityMetric + + eue::MeanEstimate + + function EUE{N,L,T,E}(eue::MeanEstimate) where {N,L,T<:Period,E<:EnergyUnit} + val(eue) >= 0 || throw(DomainError( + "$val is not a valid unserved energy expectation")) + new{N,L,T,E}(eue) + end + +end + +val(x::EUE) = val(x.eue) +stderror(x::EUE) = stderror(x.eue) + +function Base.show(io::IO, x::EUE{N,L,T,E}) where {N,L,T,E} + + print(io, "EUE = ", x.eue, " ", + unitsymbol(E), "/", N*L == 1 ? "" : N*L, unitsymbol(T)) + +end diff --git a/src/PRAS/ResourceAdequacy/results/availability.jl b/src/PRAS/ResourceAdequacy/results/availability.jl new file mode 100644 index 0000000..774513b --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/availability.jl @@ -0,0 +1,96 @@ +abstract type AbstractAvailabilityResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractAvailabilityResult, ::Colon, t::ZonedDateTime) = + getindex.(x, names(x), t) + +getindex(x::AbstractAvailabilityResult, name::String, ::Colon) = + getindex.(x, name, x.timestamps) + +getindex(x::AbstractAvailabilityResult, ::Colon, ::Colon) = + getindex.(x, names(x), permutedims(x.timestamps)) + +# Full Generator availability data + +struct GeneratorAvailability <: ResultSpec end + +struct GeneratorAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} + + generators::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + available::Array{Bool,3} + +end + +names(x::GeneratorAvailabilityResult) = x.generators + +function getindex(x::GeneratorAvailabilityResult, g::AbstractString, t::ZonedDateTime) + i_g = findfirstunique(x.generators, g) + i_t = findfirstunique(x.timestamps, t) + return vec(x.available[i_g, i_t, :]) +end + +# Full Storage availability data + +struct StorageAvailability <: ResultSpec end + +struct StorageAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} + + storages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + available::Array{Bool,3} + +end + +names(x::StorageAvailabilityResult) = x.storages + +function getindex(x::StorageAvailabilityResult, s::AbstractString, t::ZonedDateTime) + i_s = findfirstunique(x.storages, s) + i_t = findfirstunique(x.timestamps, t) + return vec(x.available[i_s, i_t, :]) +end + +# Full GeneratorStorage availability data + +struct GeneratorStorageAvailability <: ResultSpec end + +struct GeneratorStorageAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} + + generatorstorages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + available::Array{Bool,3} + +end + +names(x::GeneratorStorageAvailabilityResult) = x.generatorstorages + +function getindex(x::GeneratorStorageAvailabilityResult, gs::AbstractString, t::ZonedDateTime) + i_gs = findfirstunique(x.generatorstorages, gs) + i_t = findfirstunique(x.timestamps, t) + return vec(x.available[i_gs, i_t, :]) +end + +# Full Line availability data + +struct LineAvailability <: ResultSpec end + +struct LineAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} + + lines::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + available::Array{Bool,3} + +end + +names(x::LineAvailabilityResult) = x.lines + +function getindex(x::LineAvailabilityResult, l::AbstractString, t::ZonedDateTime) + i_l = findfirstunique(x.lines, l) + i_t = findfirstunique(x.timestamps, t) + return vec(x.available[i_l, i_t, :]) +end diff --git a/src/PRAS/ResourceAdequacy/results/energy.jl b/src/PRAS/ResourceAdequacy/results/energy.jl new file mode 100644 index 0000000..b121c4a --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/energy.jl @@ -0,0 +1,127 @@ +abstract type AbstractEnergyResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractEnergyResult, ::Colon) = + getindex.(x, x.timestamps) + +getindex(x::AbstractEnergyResult, ::Colon, t::ZonedDateTime) = + getindex.(x, names(x), t) + +getindex(x::AbstractEnergyResult, name::String, ::Colon) = + getindex.(x, name, x.timestamps) + +getindex(x::AbstractEnergyResult, ::Colon, ::Colon) = + getindex.(x, names(x), permutedims(x.timestamps)) + +# Sample-averaged Storage state-of-charge data + +struct StorageEnergy <: ResultSpec end + +struct StorageEnergyResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} + + nsamples::Union{Int,Nothing} + storages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + energy_mean::Matrix{Float64} + + energy_period_std::Vector{Float64} + energy_regionperiod_std::Matrix{Float64} + +end + +names(x::StorageEnergyResult) = x.storages + +function getindex(x::StorageEnergyResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return sum(view(x.energy_mean, :, i_t)), x.energy_period_std[i_t] +end + +function getindex(x::StorageEnergyResult, s::AbstractString, t::ZonedDateTime) + i_s = findfirstunique(x.storages, s) + i_t = findfirstunique(x.timestamps, t) + return x.energy_mean[i_s, i_t], x.energy_regionperiod_std[i_s, i_t] +end + +# Sample-averaged GeneratorStorage state-of-charge data + +struct GeneratorStorageEnergy <: ResultSpec end + +struct GeneratorStorageEnergyResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} + + nsamples::Union{Int,Nothing} + generatorstorages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + energy_mean::Matrix{Float64} + + energy_period_std::Vector{Float64} + energy_regionperiod_std::Matrix{Float64} + +end + +names(x::GeneratorStorageEnergyResult) = x.generatorstorages + +function getindex(x::GeneratorStorageEnergyResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return sum(view(x.energy_mean, :, i_t)), x.energy_period_std[i_t] +end + +function getindex(x::GeneratorStorageEnergyResult, gs::AbstractString, t::ZonedDateTime) + i_gs = findfirstunique(x.generatorstorages, gs) + i_t = findfirstunique(x.timestamps, t) + return x.energy_mean[i_gs, i_t], x.energy_regionperiod_std[i_gs, i_t] +end + +# Full Storage state-of-charge data + +struct StorageEnergySamples <: ResultSpec end + +struct StorageEnergySamplesResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} + + storages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + energy::Array{Int,3} + +end + +names(x::StorageEnergySamplesResult) = x.storages + +function getindex(x::StorageEnergySamplesResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return vec(sum(view(x.energy, :, i_t, :), dims=1)) +end + +function getindex(x::StorageEnergySamplesResult, s::AbstractString, t::ZonedDateTime) + i_s = findfirstunique(x.storages, s) + i_t = findfirstunique(x.timestamps, t) + return vec(x.energy[i_s, i_t, :]) +end + +# Full GeneratorStorage state-of-charge data + +struct GeneratorStorageEnergySamples <: ResultSpec end + +struct GeneratorStorageEnergySamplesResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} + + generatorstorages::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + energy::Array{Int,3} + +end + +names(x::GeneratorStorageEnergySamplesResult) = x.generatorstorages + +function getindex(x::GeneratorStorageEnergySamplesResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return vec(sum(view(x.energy, :, i_t, :), dims=1)) +end + +function getindex(x::GeneratorStorageEnergySamplesResult, gs::AbstractString, t::ZonedDateTime) + i_gs = findfirstunique(x.generatorstorages, gs) + i_t = findfirstunique(x.timestamps, t) + return vec(x.energy[i_gs, i_t, :]) +end diff --git a/src/PRAS/ResourceAdequacy/results/flow.jl b/src/PRAS/ResourceAdequacy/results/flow.jl new file mode 100644 index 0000000..d8c11fc --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/flow.jl @@ -0,0 +1,71 @@ +struct Flow <: ResultSpec end +abstract type AbstractFlowResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractFlowResult, ::Colon) = + getindex.(x, x.interfaces) + +getindex(x::AbstractFlowResult, ::Colon, t::ZonedDateTime) = + getindex.(x, x.interfaces, t) + +getindex(x::AbstractFlowResult, i::Pair{<:AbstractString,<:AbstractString}, ::Colon) = + getindex.(x, i, x.timestamps) + +getindex(x::AbstractFlowResult, ::Colon, ::Colon) = + getindex.(x, x.interfaces, permutedims(x.timestamps)) + +# Sample-averaged flow data + +struct FlowResult{N,L,T<:Period,P<:PowerUnit} <: AbstractFlowResult{N,L,T} + + nsamples::Union{Int,Nothing} + interfaces::Vector{Pair{String,String}} + timestamps::StepRange{ZonedDateTime,T} + + flow_mean::Matrix{Float64} + + flow_interface_std::Vector{Float64} + flow_interfaceperiod_std::Matrix{Float64} + +end + +function getindex(x::FlowResult, i::Pair{<:AbstractString,<:AbstractString}) + i_i, reverse = findfirstunique_directional(x.interfaces, i) + flow = mean(view(x.flow_mean, i_i, :)) + return reverse ? -flow : flow, x.flow_interface_std[i_i] +end + +function getindex(x::FlowResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) + i_i, reverse = findfirstunique_directional(x.interfaces, i) + i_t = findfirstunique(x.timestamps, t) + flow = x.flow_mean[i_i, i_t] + return reverse ? -flow : flow, x.flow_interfaceperiod_std[i_i, i_t] +end + +# Full flow data + +struct FlowSamples <: ResultSpec end + +struct FlowSamplesResult{N,L,T<:Period,P<:PowerUnit} <: AbstractFlowResult{N,L,T} + + interfaces::Vector{Pair{String,String}} + timestamps::StepRange{ZonedDateTime,T} + + flow::Array{Int,3} + +end + +function getindex(x::FlowSamplesResult, i::Pair{<:AbstractString,<:AbstractString}) + i_i, reverse = findfirstunique_directional(x.interfaces, i) + flow = vec(mean(view(x.flow, i_i, :, :), dims=1)) + return reverse ? -flow : flow +end + + +function getindex(x::FlowSamplesResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) + i_i, reverse = findfirstunique_directional(x.interfaces, i) + i_t = findfirstunique(x.timestamps, t) + flow = vec(x.flow[i_i, i_t, :]) + return reverse ? -flow : flow +end diff --git a/src/PRAS/ResourceAdequacy/results/results.jl b/src/PRAS/ResourceAdequacy/results/results.jl new file mode 100644 index 0000000..895da22 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/results.jl @@ -0,0 +1,39 @@ +broadcastable(x::ResultSpec) = Ref(x) +broadcastable(x::Result) = Ref(x) + +include("shortfall.jl") +include("surplus.jl") +include("flow.jl") +include("utilization.jl") +include("availability.jl") +include("energy.jl") + +function resultchannel( + method::SimulationSpec, results::T, threads::Int +) where T <: Tuple{Vararg{ResultSpec}} + + types = accumulatortype.(method, results) + return Channel{Tuple{types...}}(threads) + +end + +merge!(xs::T, ys::T) where T <: Tuple{Vararg{ResultAccumulator}} = + foreach(merge!, xs, ys) + +function finalize( + results::Channel{<:Tuple{Vararg{ResultAccumulator}}}, + system::SystemModel{N,L,T,P,E}, + threads::Int +) where {N,L,T,P,E} + + total_result = take!(results) + + for _ in 2:threads + thread_result = take!(results) + merge!(total_result, thread_result) + end + close(results) + + return finalize.(total_result, system) + +end diff --git a/src/PRAS/ResourceAdequacy/results/shortfall.jl b/src/PRAS/ResourceAdequacy/results/shortfall.jl new file mode 100644 index 0000000..2eb8935 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/shortfall.jl @@ -0,0 +1,257 @@ +struct Shortfall <: ResultSpec end +abstract type AbstractShortfallResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = + getindex.(x, x.regions, t) + +getindex(x::AbstractShortfallResult, r::AbstractString, ::Colon) = + getindex.(x, r, x.timestamps) + +getindex(x::AbstractShortfallResult, ::Colon, ::Colon) = + getindex.(x, x.regions, permutedims(x.timestamps)) + + +LOLE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = + LOLE.(x, x.regions, t) + +LOLE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = + LOLE.(x, r, x.timestamps) + +LOLE(x::AbstractShortfallResult, ::Colon, ::Colon) = + LOLE.(x, x.regions, permutedims(x.timestamps)) + + +EUE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = + EUE.(x, x.regions, t) + +EUE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = + EUE.(x, r, x.timestamps) + +EUE(x::AbstractShortfallResult, ::Colon, ::Colon) = + EUE.(x, x.regions, permutedims(x.timestamps)) + +# Sample-averaged shortfall data + +struct ShortfallResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractShortfallResult{N,L,T} + + nsamples::Union{Int,Nothing} + regions::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + eventperiod_mean::Float64 + eventperiod_std::Float64 + + eventperiod_region_mean::Vector{Float64} + eventperiod_region_std::Vector{Float64} + + eventperiod_period_mean::Vector{Float64} + eventperiod_period_std::Vector{Float64} + + eventperiod_regionperiod_mean::Matrix{Float64} + eventperiod_regionperiod_std::Matrix{Float64} + + + shortfall_mean::Matrix{Float64} # r x t + + shortfall_std::Float64 + shortfall_region_std::Vector{Float64} + shortfall_period_std::Vector{Float64} + shortfall_regionperiod_std::Matrix{Float64} + + function ShortfallResult{N,L,T,E}( + nsamples::Union{Int,Nothing}, + regions::Vector{String}, + timestamps::StepRange{ZonedDateTime,T}, + eventperiod_mean::Float64, + eventperiod_std::Float64, + eventperiod_region_mean::Vector{Float64}, + eventperiod_region_std::Vector{Float64}, + eventperiod_period_mean::Vector{Float64}, + eventperiod_period_std::Vector{Float64}, + eventperiod_regionperiod_mean::Matrix{Float64}, + eventperiod_regionperiod_std::Matrix{Float64}, + shortfall_mean::Matrix{Float64}, + shortfall_std::Float64, + shortfall_region_std::Vector{Float64}, + shortfall_period_std::Vector{Float64}, + shortfall_regionperiod_std::Matrix{Float64} + ) where {N,L,T<:Period,E<:EnergyUnit} + + isnothing(nsamples) || nsamples > 0 || + throw(DomainError("Sample count must be positive or `nothing`.")) + + + length(timestamps) == N || + error("The provided timestamp range does not match the simulation length") + + nregions = length(regions) + + length(eventperiod_region_mean) == nregions && + length(eventperiod_region_std) == nregions && + length(eventperiod_period_mean) == N && + length(eventperiod_period_std) == N && + size(eventperiod_regionperiod_mean) == (nregions, N) && + size(eventperiod_regionperiod_std) == (nregions, N) && + length(shortfall_region_std) == nregions && + length(shortfall_period_std) == N && + size(shortfall_regionperiod_std) == (nregions, N) || + error("Inconsistent input data sizes") + + new{N,L,T,E}(nsamples, regions, timestamps, + eventperiod_mean, eventperiod_std, + eventperiod_region_mean, eventperiod_region_std, + eventperiod_period_mean, eventperiod_period_std, + eventperiod_regionperiod_mean, eventperiod_regionperiod_std, + shortfall_mean, shortfall_std, + shortfall_region_std, shortfall_period_std, + shortfall_regionperiod_std) + + end + +end + +function getindex(x::ShortfallResult) + return sum(x.shortfall_mean), x.shortfall_std +end + +function getindex(x::ShortfallResult, r::AbstractString) + i_r = findfirstunique(x.regions, r) + return sum(view(x.shortfall_mean, i_r, :)), x.shortfall_region_std[i_r] +end + +function getindex(x::ShortfallResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return sum(view(x.shortfall_mean, :, i_t)), x.shortfall_period_std[i_t] +end + +function getindex(x::ShortfallResult, r::AbstractString, t::ZonedDateTime) + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + return x.shortfall_mean[i_r, i_t], x.shortfall_regionperiod_std[i_r, i_t] +end + + +LOLE(x::ShortfallResult{N,L,T}) where {N,L,T} = + LOLE{N,L,T}(MeanEstimate(x.eventperiod_mean, + x.eventperiod_std, + x.nsamples)) + +function LOLE(x::ShortfallResult{N,L,T}, r::AbstractString) where {N,L,T} + i_r = findfirstunique(x.regions, r) + return LOLE{N,L,T}(MeanEstimate(x.eventperiod_region_mean[i_r], + x.eventperiod_region_std[i_r], + x.nsamples)) +end + +function LOLE(x::ShortfallResult{N,L,T}, t::ZonedDateTime) where {N,L,T} + i_t = findfirstunique(x.timestamps, t) + return LOLE{1,L,T}(MeanEstimate(x.eventperiod_period_mean[i_t], + x.eventperiod_period_std[i_t], + x.nsamples)) +end + +function LOLE(x::ShortfallResult{N,L,T}, r::AbstractString, t::ZonedDateTime) where {N,L,T} + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + return LOLE{1,L,T}(MeanEstimate(x.eventperiod_regionperiod_mean[i_r, i_t], + x.eventperiod_regionperiod_std[i_r, i_t], + x.nsamples)) +end + + +EUE(x::ShortfallResult{N,L,T,E}) where {N,L,T,E} = + EUE{N,L,T,E}(MeanEstimate(x[]..., x.nsamples)) + +EUE(x::ShortfallResult{N,L,T,E}, r::AbstractString) where {N,L,T,E} = + EUE{N,L,T,E}(MeanEstimate(x[r]..., x.nsamples)) + +EUE(x::ShortfallResult{N,L,T,E}, t::ZonedDateTime) where {N,L,T,E} = + EUE{1,L,T,E}(MeanEstimate(x[t]..., x.nsamples)) + +EUE(x::ShortfallResult{N,L,T,E}, r::AbstractString, t::ZonedDateTime) where {N,L,T,E} = + EUE{1,L,T,E}(MeanEstimate(x[r, t]..., x.nsamples)) + +# Full shortfall data + +struct ShortfallSamples <: ResultSpec end + +struct ShortfallSamplesResult{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractShortfallResult{N,L,T} + + regions::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + shortfall::Array{Int,3} # r x t x s + +end + +function getindex( + x::ShortfallSamplesResult{N,L,T,P,E} +) where {N,L,T,P,E} + p2e = conversionfactor(L, T, P, E) + return vec(p2e * sum(x.shortfall, dims=1:2)) +end + +function getindex( + x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString +) where {N,L,T,P,E} + i_r = findfirstunique(x.regions, r) + p2e = conversionfactor(L, T, P, E) + return vec(p2e * sum(view(x.shortfall, i_r, :, :), dims=1)) +end + +function getindex( + x::ShortfallSamplesResult{N,L,T,P,E}, t::ZonedDateTime +) where {N,L,T,P,E} + i_t = findfirstunique(x.timestamps, t) + p2e = conversionfactor(L, T, P, E) + return vec(p2e * sum(view(x.shortfall, :, i_t, :), dims=1)) +end + +function getindex( + x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString, t::ZonedDateTime +) where {N,L,T,P,E} + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + p2e = conversionfactor(L, T, P, E) + return vec(p2e * x.shortfall[i_r, i_t, :]) +end + + +function LOLE(x::ShortfallSamplesResult{N,L,T}) where {N,L,T} + eventperiods = sum(sum(x.shortfall, dims=1) .> 0, dims=2) + return LOLE{N,L,T}(MeanEstimate(eventperiods)) +end + +function LOLE(x::ShortfallSamplesResult{N,L,T}, r::AbstractString) where {N,L,T} + i_r = findfirstunique(x.regions, r) + eventperiods = sum(view(x.shortfall, i_r, :, :) .> 0, dims=1) + return LOLE{N,L,T}(MeanEstimate(eventperiods)) +end + +function LOLE(x::ShortfallSamplesResult{N,L,T}, t::ZonedDateTime) where {N,L,T} + i_t = findfirstunique(x.timestamps, t) + eventperiods = sum(view(x.shortfall, :, i_t, :), dims=1) .> 0 + return LOLE{1,L,T}(MeanEstimate(eventperiods)) +end + +function LOLE(x::ShortfallSamplesResult{N,L,T}, r::AbstractString, t::ZonedDateTime) where {N,L,T} + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + eventperiods = view(x.shortfall, i_r, i_t, :) .> 0 + return LOLE{1,L,T}(MeanEstimate(eventperiods)) +end + + +EUE(x::ShortfallSamplesResult{N,L,T,P,E}) where {N,L,T,P,E} = + EUE{N,L,T,E}(MeanEstimate(x[])) + +EUE(x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString) where {N,L,T,P,E} = + EUE{N,L,T,E}(MeanEstimate(x[r])) + +EUE(x::ShortfallSamplesResult{N,L,T,P,E}, t::ZonedDateTime) where {N,L,T,P,E} = + EUE{1,L,T,E}(MeanEstimate(x[t])) + +EUE(x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString, t::ZonedDateTime) where {N,L,T,P,E} = + EUE{1,L,T,E}(MeanEstimate(x[r, t])) diff --git a/src/PRAS/ResourceAdequacy/results/surplus.jl b/src/PRAS/ResourceAdequacy/results/surplus.jl new file mode 100644 index 0000000..a3ab03c --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/surplus.jl @@ -0,0 +1,66 @@ +struct Surplus <: ResultSpec end +abstract type AbstractSurplusResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractSurplusResult, ::Colon) = + getindex.(x, x.timestamps) + +getindex(x::AbstractSurplusResult, ::Colon, t::ZonedDateTime) = + getindex.(x, x.regions, t) + +getindex(x::AbstractSurplusResult, r::AbstractString, ::Colon) = + getindex.(x, r, x.timestamps) + +getindex(x::AbstractSurplusResult, ::Colon, ::Colon) = + getindex.(x, x.regions, permutedims(x.timestamps)) + +# Sample-averaged surplus data + +struct SurplusResult{N,L,T<:Period,P<:PowerUnit} <: AbstractSurplusResult{N,L,T} + + nsamples::Union{Int,Nothing} + regions::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + surplus_mean::Matrix{Float64} + + surplus_period_std::Vector{Float64} + surplus_regionperiod_std::Matrix{Float64} + +end + +function getindex(x::SurplusResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return sum(view(x.surplus_mean, :, i_t)), x.surplus_period_std[i_t] +end + +function getindex(x::SurplusResult, r::AbstractString, t::ZonedDateTime) + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + return x.surplus_mean[i_r, i_t], x.surplus_regionperiod_std[i_r, i_t] +end + +# Full surplus data + +struct SurplusSamples <: ResultSpec end + +struct SurplusSamplesResult{N,L,T<:Period,P<:PowerUnit} <: AbstractSurplusResult{N,L,T} + + regions::Vector{String} + timestamps::StepRange{ZonedDateTime,T} + + surplus::Array{Int,3} + +end + +function getindex(x::SurplusSamplesResult, t::ZonedDateTime) + i_t = findfirstunique(x.timestamps, t) + return vec(sum(view(x.surplus, :, i_t, :), dims=1)) +end + +function getindex(x::SurplusSamplesResult, r::AbstractString, t::ZonedDateTime) + i_r = findfirstunique(x.regions, r) + i_t = findfirstunique(x.timestamps, t) + return vec(x.surplus[i_r, i_t, :]) +end diff --git a/src/PRAS/ResourceAdequacy/results/utilization.jl b/src/PRAS/ResourceAdequacy/results/utilization.jl new file mode 100644 index 0000000..e17e007 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/results/utilization.jl @@ -0,0 +1,69 @@ +struct Utilization <: ResultSpec end +abstract type AbstractUtilizationResult{N,L,T} <: Result{N,L,T} end + +# Colon indexing + +getindex(x::AbstractUtilizationResult, ::Colon) = + getindex.(x, x.interfaces) + +getindex(x::AbstractUtilizationResult, ::Colon, t::ZonedDateTime) = + getindex.(x, x.interfaces, t) + +getindex(x::AbstractUtilizationResult, i::Pair{<:AbstractString,<:AbstractString}, ::Colon) = + getindex.(x, i, x.timestamps) + +getindex(x::AbstractUtilizationResult, ::Colon, ::Colon) = + getindex.(x, x.interfaces, permutedims(x.timestamps)) + +# Sample-averaged utilization data + +struct UtilizationResult{N,L,T<:Period} <: AbstractUtilizationResult{N,L,T} + + nsamples::Union{Int,Nothing} + interfaces::Vector{Pair{String,String}} + timestamps::StepRange{ZonedDateTime,T} + + utilization_mean::Matrix{Float64} + + utilization_interface_std::Vector{Float64} + utilization_interfaceperiod_std::Matrix{Float64} + +end + +function getindex(x::UtilizationResult, i::Pair{<:AbstractString,<:AbstractString}) + i_i, _ = findfirstunique_directional(x.interfaces, i) + return mean(view(x.utilization_mean, i_i, :)), x.utilization_interface_std[i_i] +end + +function getindex(x::UtilizationResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) + i_i, _ = findfirstunique_directional(x.interfaces, i) + i_t = findfirstunique(x.timestamps, t) + return x.utilization_mean[i_i, i_t], x.utilization_interfaceperiod_std[i_i, i_t] +end + +# Full utilization data + +struct UtilizationSamples <: ResultSpec end + +struct UtilizationSamplesResult{N,L,T<:Period} <: AbstractUtilizationResult{N,L,T} + + interfaces::Vector{Pair{String,String}} + timestamps::StepRange{ZonedDateTime,T} + + utilization::Array{Float64,3} + +end + +function getindex(x::UtilizationSamplesResult, + i::Pair{<:AbstractString,<:AbstractString}) + i_i, _ = findfirstunique_directional(x.interfaces, i) + return vec(mean(view(x.utilization, i_i, :, :), dims=1)) +end + + +function getindex(x::UtilizationSamplesResult, + i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) + i_i, _ = findfirstunique_directional(x.interfaces, i) + i_t = findfirstunique(x.timestamps, t) + return vec(x.utilization[i_i, i_t, :]) +end diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl new file mode 100644 index 0000000..4b0224b --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl @@ -0,0 +1,89 @@ +include("conv.jl") + +struct Convolution <: SimulationSpec + + verbose::Bool + threaded::Bool + + Convolution(;verbose::Bool=false, threaded::Bool=true) = + new(verbose, threaded) + +end + +function assess( + system::SystemModel{N}, + method::Convolution, + resultspecs::ResultSpec... +) where {N} + + nregions = length(system.regions) + nstors = length(system.storages) + ngenstors = length(system.generatorstorages) + + if nregions > 1 + @warn "$method is a copper plate simulation method. " * + "Transmission constraints between the system's $nregions " * + "regions will be ignored in this assessment." + end + + if nstors + ngenstors > 0 + resources = String[] + nstors > 0 && push!(resources, "$nstors Storage") + ngenstors > 0 && push!(resources, "$ngenstors GeneratorStorage") + @warn "$method is a non-sequential simulation method. " * + "The system's " * join(resources, " and ") * " resources " * + "will be ignored in this assessment." + end + + threads = nthreads() + periods = Channel{Int}(2*threads) + results = resultchannel(method, resultspecs, threads) + + @spawn makeperiods(periods, N) + + if method.threaded + + if (threads == 1) + @warn "It looks like you haven't configured JULIA_NUM_THREADS before you started the julia repl. \n If you want to use multi-threading, stop the execution and start your julia repl using : \n julia --project --threads auto" + end + + for _ in 1:threads + @spawn assess(system, method, periods, results, resultspecs...) + end + else + assess(system, method, periods, results, resultspecs...) + end + + return finalize(results, system, method.threaded ? threads : 1) + +end + +function makeperiods(periods::Channel{Int}, N::Int) + for t in 1:N + put!(periods, t) + end + close(periods) +end + +function assess( + system::SystemModel{N,L,T,P,E}, method::Convolution, + periods::Channel{Int}, + results::Channel{<:Tuple{Vararg{ResultAccumulator{Convolution}}}}, + resultspecs::ResultSpec... +) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} + + accs = accumulator.(system, method, resultspecs) + + for t in periods + + distr = CapacityDistribution(system, t) + foreach(acc -> record!(acc, t, distr), accs) + + end + + put!(results, accs) + +end + +include("result_shortfall.jl") +include("result_surplus.jl") diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl new file mode 100644 index 0000000..b2892f1 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl @@ -0,0 +1,152 @@ +CapacityDistribution = + DiscreteNonParametric{Int,Float64,Vector{Int},Vector{Float64}} + +function (::Type{CapacityDistribution})(system::SystemModel, t::Int) + + capacities = system.generators.capacity[:, t] + + μ = system.generators.μ[:, t] + λ = system.generators.λ[:, t] + availabilities = μ ./ (μ .+ λ) + + result = spconv(capacities, availabilities) + support(result) .-= colsum(system.regions.load, t) + + return result + +end + +function assess(distr::CapacityDistribution) + + xs = support(distr) + ps = probs(distr) + + i = 1 + lolp = 0. + eul = 0. + + while i <= length(xs) + + xs[i] >= 0 && break + lolp += ps[i] + eul -= ps[i] * xs[i] + i += 1 + + end + + return lolp, eul + +end + +function surplus(distr::CapacityDistribution) + + xs = support(distr) + ps = probs(distr) + + i = 1 + es = 0. + + for i in 1:length(xs) + xs[i] <= 0 && continue + es += ps[i] * xs[i] + end + + return es + +end + +function spconv(hvsraw::AbstractVector{Int}, hpsraw::AbstractVector{Float64}) + + zeroidxs = hvsraw .!= 0 + hvs = hvsraw[zeroidxs] + hps = hpsraw[zeroidxs] + + length(hvs) == 0 && + return DiscreteNonParametric([0], [1.], check_args=false) + + max_n = sum(hvs) + 1 + current_probs = Vector{Float64}(undef, max_n) + prev_probs = Vector{Float64}(undef, max_n) + current_values = Vector{Int}(undef, max_n) + prev_values = Vector{Int}(undef, max_n) + + current_n = 2 + current_values[1:current_n] = [0, hvs[1]] + current_probs[1:current_n] = [1 - hps[1], hps[1]] + + for (hv, hp) in zip(hvs[2:end], hps[2:end]) + current_values, current_probs, current_n, prev_values, prev_probs = + spconv!(prev_values, prev_probs, hv, hp, + current_values, current_probs, current_n) + end + + resize!(current_values, current_n) + resize!(current_probs, current_n) + nonzeroprob_idxs = findall(x -> x>0, current_probs) + + return DiscreteNonParametric( + current_values[nonzeroprob_idxs], + current_probs[nonzeroprob_idxs], + check_args=false) + +end + +function spconv!(y_values::Vector{Int}, y_probs::Vector{Float64}, + h_value::Int, h_prob::Float64, + x_values::Vector{Int}, x_probs::Vector{Float64}, nx::Int) + + h_q = 1 - h_prob + + ix = ixsh = 1 + iy = 0 + lastval = -1 + + @inbounds while ix <= nx + + x = x_values[ix] + xsh = x_values[ixsh] + h_value + + if lastval == x + @fastmath y_probs[iy] += h_q * x_probs[ix] + ix += 1 + + elseif lastval == xsh + @fastmath y_probs[iy] += h_prob * x_probs[ixsh] + ixsh += 1 + + elseif x == xsh + iy += 1 + y_values[iy] = x + @fastmath y_probs[iy] = h_q * x_probs[ix] + h_prob * x_probs[ixsh] + lastval = x + ix += 1 + ixsh += 1 + + elseif x < xsh + iy += 1 + y_values[iy] = x + @fastmath y_probs[iy] = h_q * x_probs[ix] + lastval = x + ix += 1 + + elseif xsh < x + iy += 1 + y_values[iy] = xsh + @fastmath y_probs[iy] = h_prob * x_probs[ixsh] + lastval = xsh + ixsh += 1 + + end + + end + + @inbounds while ixsh <= nx + iy += 1 + y_values[iy] = x_values[ixsh] + h_value + @fastmath y_probs[iy] = h_prob * x_probs[ixsh] + ixsh += 1 + end + + return y_values, y_probs, iy, x_values, x_probs + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl new file mode 100644 index 0000000..9821b65 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl @@ -0,0 +1,55 @@ +struct ConvolutionShortfallAccumulator <: ResultAccumulator{Convolution,Shortfall} + + lolps::Vector{Float64} + euls::Vector{Float64} + +end + +function merge!( + x::ConvolutionShortfallAccumulator, y::ConvolutionShortfallAccumulator +) + + x.lolps .+= y.lolps + x.euls .+= y.euls + return + +end + +accumulatortype(::Convolution, ::Shortfall) = ConvolutionShortfallAccumulator + +accumulator(::SystemModel{N}, ::Convolution, ::Shortfall) where {N} = + ConvolutionShortfallAccumulator(zeros(N), zeros(N)) + +function record!( + acc::ConvolutionShortfallAccumulator, + t::Int, distr::CapacityDistribution +) + + lolp, eul = assess(distr) + acc.lolps[t] = lolp + acc.euls[t] = eul + return + +end + +function finalize( + acc::ConvolutionShortfallAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + lole = sum(acc.lolps) + + p2e = conversionfactor(L,T,P,E) + eues = acc.euls .* p2e + eue = sum(eues) + + allzeros = zeros(length(acc.lolps)) + + return ShortfallResult{N,L,T,E}( + nothing, ["[PRAS] Entire System"], system.timestamps, + lole, 0., [lole], [0.], acc.lolps, allzeros, + reshape(acc.lolps, 1, :), reshape(allzeros, 1, :), + reshape(eues, 1, :), 0., [0.], allzeros, reshape(allzeros, 1, :) + ) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl new file mode 100644 index 0000000..2ff4763 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl @@ -0,0 +1,43 @@ +struct ConvolutionSurplusAccumulator <: ResultAccumulator{Convolution,Surplus} + + surplus::Vector{Float64} + +end + +function merge!( + x::ConvolutionSurplusAccumulator, y::ConvolutionSurplusAccumulator +) + + x.surplus .+= y.surplus + return + +end + +accumulatortype(::Convolution, ::Surplus) = ConvolutionSurplusAccumulator + +accumulator(::SystemModel{N}, ::Convolution, ::Surplus) where {N} = + ConvolutionSurplusAccumulator(zeros(N)) + +function record!( + acc::ConvolutionSurplusAccumulator, + t::Int, distr::CapacityDistribution +) + + acc.surplus[t] = surplus(distr) + return + +end + +function finalize( + acc::ConvolutionSurplusAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + allzeros = zeros(length(acc.surplus)) + + return SurplusResult{N,L,T,P}( + nothing, ["__EntireSystem"], system.timestamps, + reshape(acc.surplus, 1, :), allzeros, reshape(allzeros, 1, :) + ) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl new file mode 100644 index 0000000..a261a84 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl @@ -0,0 +1,422 @@ +""" + + DispatchProblem(sys::SystemModel) + +Create a min-cost flow problem for the multi-region max power delivery problem +with generation and storage discharging in decreasing order of priority, and +storage charging with excess capacity. Storage and GeneratorStorage devices +within a region are represented individually on the network. + +This involves injections/withdrawals at one node (regional capacity +surplus/shortfall) for each modelled region, as well as two/three nodes +associated with each Storage/GeneratorStorage device, and a supplementary +"slack" node in the network that can absorb undispatched power or pass +unserved energy or unused charging capability through to satisfy +power balance constraints. + +Flows from the generation nodes are free, while flows to charging and +from discharging nodes are costed or rewarded according to the +time-to-discharge of the storage device, ensuring efficient coordination +across units, while enforcing that storage is only discharged once generation +capacity is exhausted (implying an operational strategy that prioritizes +resource adequacy over economic arbitrage). This is based on the storage +dispatch strategy of Evans, Tindemans, and Angeli, as outlined in "Minimizing +Unserved Energy Using Heterogenous Storage Units" (IEEE Transactions on Power +Systems, 2019). + +Flows to the charging node have an attenuated negative cost (reward), +incentivizing immediate storage charging if generation and transmission +allows it, while avoiding charging by discharging other storage (since that +would incur an overall positive cost). + +Flows to the slack node (representing unused generation or storage discharge +capacity) are free, but flows from the slack node to serve load incur the lost +load penalty of 9999. Flows from the slack node in lieu of storage charging +or discharging are free. + +Flows on transmission interfaces assume a hurdle rate of 1 +to keep unserved energy close to the source of the shortage and eliminate +loop flows. This has the side-effect of disincentivising wheeling power across +multiple regions for charging purposes, however. + +Nodes in the problem are ordered as: + + 1. Regions generation surplus/shortfall (Regions order) + 2. Storage discharge capacity (Storage order) + 3. Storage charge capacity (Storage order) + 4. GenerationStorage inflow capacity (GeneratorStorage order) + 5. GenerationStorage discharge capacity (GeneratorStorage order) + 6. GenerationStorage grid injection (GeneratorStorage order) + 7. GenerationStorage charge capacity (GeneratorStorage order) + 8. Slack node + +Edges are ordered as: + + 1. Regions demand unserved (Regions order) + 2. Regions generation unused (Regions order) + 3. Interfaces forward flow (Interfaces order) + 4. Interfaces reverse flow (Interfaces order) + 5. Storage discharge to grid (Storage order) + 6. Storage discharge unused (Storage order) + 7. Storage charge from grid (Storage order) + 8. Storage charge unused (Storage order) + 9. GenerationStorage discharge to grid (GeneratorStorage order) + 10. GenerationStorage discharge unused (GeneratorStorage order) + 11. GenerationStorage inflow to grid (GenerationStorage order) + 12. GenerationStorage total to grid (GeneratorStorage order) + 13. GenerationStorage charge from grid (GeneratorStorage order) + 14. GenerationStorage charge from inflow (GeneratorStorage order) + 15. GenerationStorage charge unused (GeneratorStorage order) + 16. GenerationStorage inflow unused (GeneratorStorage order) + +""" +struct DispatchProblem + + fp::FlowProblem + + # Node labels + region_nodes::UnitRange{Int} + storage_discharge_nodes::UnitRange{Int} + storage_charge_nodes::UnitRange{Int} + genstorage_inflow_nodes::UnitRange{Int} + genstorage_discharge_nodes::UnitRange{Int} + genstorage_togrid_nodes::UnitRange{Int} + genstorage_charge_nodes::UnitRange{Int} + slack_node::Int + + # Edge labels + region_unserved_edges::UnitRange{Int} + region_unused_edges::UnitRange{Int} + interface_forward_edges::UnitRange{Int} + interface_reverse_edges::UnitRange{Int} + storage_discharge_edges::UnitRange{Int} + storage_dischargeunused_edges::UnitRange{Int} + storage_charge_edges::UnitRange{Int} + storage_chargeunused_edges::UnitRange{Int} + genstorage_dischargegrid_edges::UnitRange{Int} + genstorage_dischargeunused_edges::UnitRange{Int} + genstorage_inflowgrid_edges::UnitRange{Int} + genstorage_totalgrid_edges::UnitRange{Int} + genstorage_gridcharge_edges::UnitRange{Int} + genstorage_inflowcharge_edges::UnitRange{Int} + genstorage_chargeunused_edges::UnitRange{Int} + genstorage_inflowunused_edges::UnitRange{Int} + + min_chargecost::Int + max_dischargecost::Int + + function DispatchProblem( + sys::SystemModel; unlimited::Int=999_999_999) + + nregions = length(sys.regions) + nifaces = length(sys.interfaces) + nstors = length(sys.storages) + ngenstors = length(sys.generatorstorages) + + maxchargetime, maxdischargetime = maxtimetocharge_discharge(sys) + min_chargecost = - maxchargetime - 1 + max_dischargecost = - min_chargecost + maxdischargetime + 1 + shortagepenalty = 10 * (nifaces + max_dischargecost) + + stor_regions = assetgrouplist(sys.region_stor_idxs) + genstor_regions = assetgrouplist(sys.region_genstor_idxs) + + region_nodes = 1:nregions + stor_discharge_nodes = indices_after(region_nodes, nstors) + stor_charge_nodes = indices_after(stor_discharge_nodes, nstors) + genstor_inflow_nodes = indices_after(stor_charge_nodes, ngenstors) + genstor_discharge_nodes = indices_after(genstor_inflow_nodes, ngenstors) + genstor_togrid_nodes = indices_after(genstor_discharge_nodes, ngenstors) + genstor_charge_nodes = indices_after(genstor_togrid_nodes, ngenstors) + slack_node = nnodes = last(genstor_charge_nodes) + 1 + + region_unservedenergy = 1:nregions + region_unusedcapacity = indices_after(region_unservedenergy, nregions) + iface_forward = indices_after(region_unusedcapacity, nifaces) + iface_reverse = indices_after(iface_forward, nifaces) + stor_dischargeused = indices_after(iface_reverse, nstors) + stor_dischargeunused = indices_after(stor_dischargeused, nstors) + stor_chargeused = indices_after(stor_dischargeunused, nstors) + stor_chargeunused = indices_after(stor_chargeused, nstors) + genstor_dischargegrid = indices_after(stor_chargeunused, ngenstors) + genstor_dischargeunused = indices_after(genstor_dischargegrid, ngenstors) + genstor_inflowgrid = indices_after(genstor_dischargeunused, ngenstors) + genstor_totalgrid = indices_after(genstor_inflowgrid, ngenstors) + genstor_gridcharge = indices_after(genstor_totalgrid, ngenstors) + genstor_inflowcharge = indices_after(genstor_gridcharge, ngenstors) + genstor_chargeunused = indices_after(genstor_inflowcharge, ngenstors) + genstor_inflowunused = indices_after(genstor_chargeunused, ngenstors) + nedges = last(genstor_inflowunused) + + nodesfrom = Vector{Int}(undef, nedges) + nodesto = Vector{Int}(undef, nedges) + costs = zeros(Int, nedges) + limits = fill(unlimited, nedges) + injections = zeros(Int, nnodes) + + function initedges(idxs::UnitRange{Int}, from::AbstractVector{Int}, to::AbstractVector{Int}) + nodesfrom[idxs] = from + nodesto[idxs] = to + end + + function initedges(idxs::UnitRange{Int}, from::AbstractVector{Int}, to::Int) + nodesfrom[idxs] = from + nodesto[idxs] .= to + end + + function initedges(idxs::UnitRange{Int}, from::Int, to::AbstractVector{Int}) + nodesfrom[idxs] .= from + nodesto[idxs] = to + end + + # Unserved energy edges + initedges(region_unservedenergy, slack_node, region_nodes) + costs[region_unservedenergy] .= shortagepenalty + + # Unused generation edges + initedges(region_unusedcapacity, region_nodes, slack_node) + + # Transmission edges + initedges(iface_forward, sys.interfaces.regions_from, sys.interfaces.regions_to) + costs[iface_forward] .= 1 + initedges(iface_reverse, sys.interfaces.regions_to, sys.interfaces.regions_from) + costs[iface_reverse] .= 1 + + # Storage discharging / charging + initedges(stor_dischargeused, stor_discharge_nodes, stor_regions) + initedges(stor_dischargeunused, stor_discharge_nodes, slack_node) + initedges(stor_chargeused, stor_regions, stor_charge_nodes) + initedges(stor_chargeunused, slack_node, stor_charge_nodes) + + # GeneratorStorage discharging / grid injections + initedges(genstor_dischargegrid, genstor_discharge_nodes, genstor_togrid_nodes) + initedges(genstor_dischargeunused, genstor_discharge_nodes, slack_node) + initedges(genstor_inflowgrid, genstor_inflow_nodes, genstor_togrid_nodes) + initedges(genstor_totalgrid, genstor_togrid_nodes, genstor_regions) + + # GeneratorStorage charging + initedges(genstor_gridcharge, genstor_regions, genstor_charge_nodes) + initedges(genstor_inflowcharge, genstor_inflow_nodes, genstor_charge_nodes) + initedges(genstor_chargeunused, slack_node, genstor_charge_nodes) + + initedges(genstor_inflowunused, genstor_inflow_nodes, slack_node) + + return new( + + FlowProblem(nodesfrom, nodesto, limits, costs, injections), + + region_nodes, stor_discharge_nodes, stor_charge_nodes, + genstor_inflow_nodes, genstor_discharge_nodes, + genstor_togrid_nodes, genstor_charge_nodes, slack_node, + + region_unservedenergy, region_unusedcapacity, + iface_forward, iface_reverse, + stor_dischargeused, stor_dischargeunused, + stor_chargeused, stor_chargeunused, + genstor_dischargegrid, genstor_dischargeunused, genstor_inflowgrid, + genstor_totalgrid, + genstor_gridcharge, genstor_inflowcharge, genstor_chargeunused, + genstor_inflowunused, min_chargecost, max_dischargecost + ) + + end + +end + +indices_after(lastset::UnitRange{Int}, setsize::Int) = + last(lastset) .+ (1:setsize) + +function update_problem!( + problem::DispatchProblem, state::SystemState, + system::SystemModel{N,L,T,P,E}, t::Int +) where {N,L,T,P,E} + + fp = problem.fp + slack_node = fp.nodes[problem.slack_node] + + # Update regional net available injection / withdrawal (from generators) + for (r, gen_idxs) in zip(problem.region_nodes, system.region_gen_idxs) + + region_node = fp.nodes[r] + + region_netgenavailable = available_capacity( + state.gens_available, system.generators, gen_idxs, t + ) - system.regions.load[r, t] + + updateinjection!(region_node, slack_node, region_netgenavailable) + + end + + # Update bidirectional interface limits (from lines) + for (i, line_idxs) in enumerate(system.interface_line_idxs) + + interface_forwardedge = fp.edges[problem.interface_forward_edges[i]] + interface_backwardedge = fp.edges[problem.interface_reverse_edges[i]] + + lines_capacity_forward, lines_capacity_backward = + available_capacity(state.lines_available, system.lines, line_idxs, t) + + interface_capacity_forward = min( + lines_capacity_forward, system.interfaces.limit_forward[i,t]) + updateflowlimit!(interface_forwardedge, interface_capacity_forward) + + interface_capacity_backward = min( + lines_capacity_backward, system.interfaces.limit_backward[i,t]) + updateflowlimit!(interface_backwardedge, interface_capacity_backward) + + end + + # Update Storage charge/discharge limits and priorities + for (i, (charge_node, charge_edge, discharge_node, discharge_edge)) in + enumerate(zip( + problem.storage_charge_nodes, problem.storage_charge_edges, + problem.storage_discharge_nodes, problem.storage_discharge_edges)) + + stor_online = state.stors_available[i] + stor_energy = state.stors_energy[i] + maxenergy = system.storages.energy_capacity[i, t] + + # Update discharging + + maxdischarge = stor_online * system.storages.discharge_capacity[i, t] + dischargeefficiency = system.storages.discharge_efficiency[i, t] + energydischargeable = stor_energy * dischargeefficiency + + if iszero(maxdischarge) + timetodischarge = N + 1 + else + timetodischarge = round(Int, energydischargeable / maxdischarge) + end + + discharge_capacity = + min(maxdischarge, floor(Int, energytopower( + energydischargeable, E, L, T, P))) + updateinjection!( + fp.nodes[discharge_node], slack_node, discharge_capacity) + + # Largest time-to-discharge = highest priority (discharge first) + dischargecost = problem.max_dischargecost - timetodischarge # Positive cost + updateflowcost!(fp.edges[discharge_edge], dischargecost) + + # Update charging + + maxcharge = stor_online * system.storages.charge_capacity[i, t] + chargeefficiency = system.storages.charge_efficiency[i, t] + energychargeable = (maxenergy - stor_energy) / chargeefficiency + + charge_capacity = + min(maxcharge, floor(Int, energytopower( + energychargeable, E, L, T, P))) + updateinjection!( + fp.nodes[charge_node], slack_node, -charge_capacity) + + # Smallest time-to-discharge = highest priority (charge first) + chargecost = problem.min_chargecost + timetodischarge # Negative cost + updateflowcost!(fp.edges[charge_edge], chargecost) + + end + + # Update GeneratorStorage inflow/charge/discharge limits and priorities + for (i, (charge_node, gridcharge_edge, inflowcharge_edge, + discharge_node, dischargegrid_edge, totalgrid_edge, + inflow_node)) in enumerate(zip( + problem.genstorage_charge_nodes, problem.genstorage_gridcharge_edges, + problem.genstorage_inflowcharge_edges, problem.genstorage_discharge_nodes, + problem.genstorage_dischargegrid_edges, problem.genstorage_totalgrid_edges, + problem.genstorage_inflow_nodes)) + + stor_online = state.genstors_available[i] + stor_energy = state.genstors_energy[i] + maxenergy = system.generatorstorages.energy_capacity[i, t] + + # Update inflow and grid injection / withdrawal limits + + inflow_capacity = stor_online * system.generatorstorages.inflow[i, t] + updateinjection!( + fp.nodes[inflow_node], slack_node, inflow_capacity) + + gridinjection_capacity = system.generatorstorages.gridinjection_capacity[i, t] + updateflowlimit!(fp.edges[totalgrid_edge], gridinjection_capacity) + + gridwithdrawal_capacity = system.generatorstorages.gridwithdrawal_capacity[i, t] + updateflowlimit!(fp.edges[gridcharge_edge], gridwithdrawal_capacity) + + # Update discharging + + maxdischarge = stor_online * system.generatorstorages.discharge_capacity[i, t] + dischargeefficiency = system.generatorstorages.discharge_efficiency[i, t] + energydischargeable = stor_energy * dischargeefficiency + + if iszero(maxdischarge) + timetodischarge = N + 1 + else + timetodischarge = round(Int, energydischargeable / maxdischarge) + end + + discharge_capacity = + min(maxdischarge, floor(Int, energytopower( + energydischargeable, E, L, T, P))) + updateinjection!( + fp.nodes[discharge_node], slack_node, discharge_capacity) + + # Largest time-to-discharge = highest priority (discharge first) + dischargecost = problem.max_dischargecost - timetodischarge # Positive cost + updateflowcost!(fp.edges[dischargegrid_edge], dischargecost) + + # Update charging + + maxcharge = stor_online * system.generatorstorages.charge_capacity[i, t] + chargeefficiency = system.generatorstorages.charge_efficiency[i, t] + energychargeable = (maxenergy - stor_energy) / chargeefficiency + + charge_capacity = + min(maxcharge, floor(Int, energytopower( + energychargeable, E, L, T, P))) + updateinjection!( + fp.nodes[charge_node], slack_node, -charge_capacity) + + # Smallest time-to-discharge = highest priority (charge first) + chargecost = problem.min_chargecost + timetodischarge # Negative cost + updateflowcost!(fp.edges[gridcharge_edge], chargecost) + updateflowcost!(fp.edges[inflowcharge_edge], chargecost) + + end + +end + +function update_state!( + state::SystemState, problem::DispatchProblem, + system::SystemModel{N,L,T,P,E}, t::Int +) where {N,L,T,P,E} + + edges = problem.fp.edges + p2e = conversionfactor(L, T, P, E) + + for (i, e) in enumerate(problem.storage_discharge_edges) + energy = state.stors_energy[i] + energy_drop = ceil(Int, edges[e].flow * p2e / + system.storages.discharge_efficiency[i, t]) + state.stors_energy[i] = max(0, energy - energy_drop) + + end + + for (i, e) in enumerate(problem.storage_charge_edges) + state.stors_energy[i] += + ceil(Int, edges[e].flow * p2e * system.storages.charge_efficiency[i, t]) + end + + for (i, e) in enumerate(problem.genstorage_dischargegrid_edges) + energy = state.genstors_energy[i] + energy_drop = ceil(Int, edges[e].flow * p2e / + system.generatorstorages.discharge_efficiency[i, t]) + state.genstors_energy[i] = max(0, energy - energy_drop) + end + + for (i, (e1, e2)) in enumerate(zip(problem.genstorage_gridcharge_edges, + problem.genstorage_inflowcharge_edges)) + totalcharge = (edges[e1].flow + edges[e2].flow) * p2e + state.genstors_energy[i] += + ceil(Int, totalcharge * system.generatorstorages.charge_efficiency[i, t]) + end + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl new file mode 100644 index 0000000..95d5853 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl @@ -0,0 +1,170 @@ +include("SystemState.jl") +include("DispatchProblem.jl") +include("utils.jl") + +struct SequentialMonteCarlo <: SimulationSpec + + nsamples::Int + seed::UInt64 + verbose::Bool + threaded::Bool + + function SequentialMonteCarlo(; + samples::Int=10_000, seed::Integer=rand(UInt64), + verbose::Bool=false, threaded::Bool=true + ) + samples <= 0 && throw(DomainError("Sample count must be positive")) + seed < 0 && throw(DomainError("Random seed must be non-negative")) + new(samples, UInt64(seed), verbose, threaded) + end + +end + +function assess( + system::SystemModel, + method::SequentialMonteCarlo, + resultspecs::ResultSpec... +) + + threads = nthreads() + sampleseeds = Channel{Int}(2*threads) + results = resultchannel(method, resultspecs, threads) + + @spawn makeseeds(sampleseeds, method.nsamples) + + if method.threaded + + if (threads == 1) + @warn "It looks like you haven't configured JULIA_NUM_THREADS before you started the julia repl. \n If you want to use multi-threading, stop the execution and start your julia repl using : \n julia --project --threads auto" + end + + for _ in 1:threads + @spawn assess(system, method, sampleseeds, results, resultspecs...) + end + else + assess(system, method, sampleseeds, results, resultspecs...) + end + + return finalize(results, system, method.threaded ? threads : 1) + +end + +function makeseeds(sampleseeds::Channel{Int}, nsamples::Int) + + for s in 1:nsamples + put!(sampleseeds, s) + end + + close(sampleseeds) + +end + +function assess( + system::SystemModel{N}, method::SequentialMonteCarlo, + sampleseeds::Channel{Int}, + results::Channel{<:Tuple{Vararg{ResultAccumulator{SequentialMonteCarlo}}}}, + resultspecs::ResultSpec... +) where N + + dispatchproblem = DispatchProblem(system) + systemstate = SystemState(system) + recorders = accumulator.(system, method, resultspecs) + + # TODO: Test performance of Philox vs Threefry, choice of rounds + # Also consider implementing an efficient Bernoulli trial with direct + # mantissa comparison + rng = Philox4x((0, 0), 10) + + for s in sampleseeds + + seed!(rng, (method.seed, s)) + initialize!(rng, systemstate, system) + + for t in 1:N + + advance!(rng, systemstate, dispatchproblem, system, t) + solve!(dispatchproblem, systemstate, system, t) + foreach(recorder -> record!( + recorder, system, systemstate, dispatchproblem, s, t + ), recorders) + + end + + foreach(recorder -> reset!(recorder, s), recorders) + + end + + put!(results, recorders) + +end + +function initialize!( + rng::AbstractRNG, state::SystemState, system::SystemModel{N} +) where N + + initialize_availability!( + rng, state.gens_available, state.gens_nexttransition, + system.generators, N) + + initialize_availability!( + rng, state.stors_available, state.stors_nexttransition, + system.storages, N) + + initialize_availability!( + rng, state.genstors_available, state.genstors_nexttransition, + system.generatorstorages, N) + + initialize_availability!( + rng, state.lines_available, state.lines_nexttransition, + system.lines, N) + + fill!(state.stors_energy, 0) + fill!(state.genstors_energy, 0) + + return + +end + +function advance!( + rng::AbstractRNG, + state::SystemState, + dispatchproblem::DispatchProblem, + system::SystemModel{N}, t::Int) where N + + update_availability!( + rng, state.gens_available, state.gens_nexttransition, + system.generators, t, N) + + update_availability!( + rng, state.stors_available, state.stors_nexttransition, + system.storages, t, N) + + update_availability!( + rng, state.genstors_available, state.genstors_nexttransition, + system.generatorstorages, t, N) + + update_availability!( + rng, state.lines_available, state.lines_nexttransition, + system.lines, t, N) + + update_energy!(state.stors_energy, system.storages, t) + update_energy!(state.genstors_energy, system.generatorstorages, t) + + update_problem!(dispatchproblem, state, system, t) + +end + +function solve!( + dispatchproblem::DispatchProblem, state::SystemState, + system::SystemModel, t::Int +) + solveflows!(dispatchproblem.fp) + update_state!(state, dispatchproblem, system, t) +end + +include("result_shortfall.jl") +include("result_surplus.jl") +include("result_flow.jl") +include("result_utilization.jl") +include("result_energy.jl") +include("result_availability.jl") diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl new file mode 100644 index 0000000..a88296c --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl @@ -0,0 +1,45 @@ +struct SystemState + + gens_available::Vector{Bool} + gens_nexttransition::Vector{Int} + + stors_available::Vector{Bool} + stors_nexttransition::Vector{Int} + stors_energy::Vector{Int} + + genstors_available::Vector{Bool} + genstors_nexttransition::Vector{Int} + genstors_energy::Vector{Int} + + lines_available::Vector{Bool} + lines_nexttransition::Vector{Int} + + function SystemState(system::SystemModel) + + ngens = length(system.generators) + gens_available = Vector{Bool}(undef, ngens) + gens_nexttransition= Vector{Int}(undef, ngens) + + nstors = length(system.storages) + stors_available = Vector{Bool}(undef, nstors) + stors_nexttransition = Vector{Int}(undef, nstors) + stors_energy = Vector{Int}(undef, nstors) + + ngenstors = length(system.generatorstorages) + genstors_available = Vector{Bool}(undef, ngenstors) + genstors_nexttransition = Vector{Int}(undef, ngenstors) + genstors_energy = Vector{Int}(undef, ngenstors) + + nlines = length(system.lines) + lines_available = Vector{Bool}(undef, nlines) + lines_nexttransition = Vector{Int}(undef, nlines) + + return new( + gens_available, gens_nexttransition, + stors_available, stors_nexttransition, stors_energy, + genstors_available, genstors_nexttransition, genstors_energy, + lines_available, lines_nexttransition) + + end + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl new file mode 100644 index 0000000..8c8a6ec --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl @@ -0,0 +1,219 @@ +# GeneratorAvailability + +struct SMCGenAvailabilityAccumulator <: + ResultAccumulator{SequentialMonteCarlo,GeneratorAvailability} + + available::Array{Bool,3} + +end + +function merge!( + x::SMCGenAvailabilityAccumulator, y::SMCGenAvailabilityAccumulator +) + + x.available .|= y.available + return + +end + +accumulatortype(::SequentialMonteCarlo, ::GeneratorAvailability) = SMCGenAvailabilityAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorAvailability +) where {N} + + ngens = length(sys.generators) + available = zeros(Bool, ngens, N, simspec.nsamples) + + return SMCGenAvailabilityAccumulator(available) + +end + +function record!( + acc::SMCGenAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.available[:, t, sampleid] .= state.gens_available + return + +end + +reset!(acc::SMCGenAvailabilityAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCGenAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return GeneratorAvailabilityResult{N,L,T}( + system.generators.names, system.timestamps, acc.available) + +end + +# StorageAvailability + +struct SMCStorAvailabilityAccumulator <: + ResultAccumulator{SequentialMonteCarlo,StorageAvailability} + + available::Array{Bool,3} + +end + +function merge!( + x::SMCStorAvailabilityAccumulator, y::SMCStorAvailabilityAccumulator +) + + x.available .|= y.available + return + +end + +accumulatortype(::SequentialMonteCarlo, ::StorageAvailability) = SMCStorAvailabilityAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::StorageAvailability +) where {N} + + nstors = length(sys.storages) + available = zeros(Bool, nstors, N, simspec.nsamples) + + return SMCStorAvailabilityAccumulator(available) + +end + +function record!( + acc::SMCStorAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.available[:, t, sampleid] .= state.stors_available + return + +end + +reset!(acc::SMCStorAvailabilityAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCStorAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return StorageAvailabilityResult{N,L,T}( + system.storages.names, system.timestamps, acc.available) + +end + +# GeneratorStorageAvailability + +struct SMCGenStorAvailabilityAccumulator <: + ResultAccumulator{SequentialMonteCarlo,GeneratorStorageAvailability} + + available::Array{Bool,3} + +end + +function merge!( + x::SMCGenStorAvailabilityAccumulator, y::SMCGenStorAvailabilityAccumulator +) + + x.available .|= y.available + return + +end + +accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageAvailability) = SMCGenStorAvailabilityAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorStorageAvailability +) where {N} + + ngenstors = length(sys.generatorstorages) + available = zeros(Bool, ngenstors, N, simspec.nsamples) + + return SMCGenStorAvailabilityAccumulator(available) + +end + +function record!( + acc::SMCGenStorAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.available[:, t, sampleid] .= state.genstors_available + return + +end + +reset!(acc::SMCGenStorAvailabilityAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCGenStorAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return GeneratorStorageAvailabilityResult{N,L,T}( + system.generatorstorages.names, system.timestamps, acc.available) + +end + +# LineAvailability + +struct SMCLineAvailabilityAccumulator <: + ResultAccumulator{SequentialMonteCarlo,LineAvailability} + + available::Array{Bool,3} + +end + +function merge!( + x::SMCLineAvailabilityAccumulator, y::SMCLineAvailabilityAccumulator +) + + x.available .|= y.available + return + +end + +accumulatortype(::SequentialMonteCarlo, ::LineAvailability) = SMCLineAvailabilityAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::LineAvailability +) where {N} + + nlines = length(sys.lines) + available = zeros(Bool, nlines, N, simspec.nsamples) + + return SMCLineAvailabilityAccumulator(available) + +end + +function record!( + acc::SMCLineAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.available[:, t, sampleid] .= state.lines_available + return + +end + +reset!(acc::SMCLineAvailabilityAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCLineAvailabilityAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return LineAvailabilityResult{N,L,T}( + system.lines.names, system.timestamps, acc.available) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl new file mode 100644 index 0000000..5fc3e9b --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl @@ -0,0 +1,273 @@ +# StorageEnergy + +mutable struct SMCStorageEnergyAccumulator <: + ResultAccumulator{SequentialMonteCarlo,StorageEnergy} + + # Cross-simulation energy mean/variances + energy_period::Vector{MeanVariance} + energy_storageperiod::Matrix{MeanVariance} + +end + +function merge!( + x::SMCStorageEnergyAccumulator, y::SMCStorageEnergyAccumulator +) + + foreach(merge!, x.energy_period, y.energy_period) + foreach(merge!, x.energy_storageperiod, y.energy_storageperiod) + + return + +end + +accumulatortype(::SequentialMonteCarlo, ::StorageEnergy) = SMCStorageEnergyAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::StorageEnergy +) where {N} + + nstorages = length(sys.storages) + + energy_period = [meanvariance() for _ in 1:N] + energy_storageperiod = [meanvariance() for _ in 1:nstorages, _ in 1:N] + + return SMCStorageEnergyAccumulator( + energy_period, energy_storageperiod) + +end + +function record!( + acc::SMCStorageEnergyAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + totalenergy = 0 + nstorages = length(system.storages) + + for s in 1:nstorages + + storageenergy = state.stors_energy[s] + fit!(acc.energy_storageperiod[s,t], storageenergy) + totalenergy += storageenergy + + end + + fit!(acc.energy_period[t], totalenergy) + + return + +end + +reset!(acc::SMCStorageEnergyAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCStorageEnergyAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + _, period_std = mean_std(acc.energy_period) + storageperiod_mean, storageperiod_std = mean_std(acc.energy_storageperiod) + + nsamples = first(first(acc.energy_period).stats).n + + return StorageEnergyResult{N,L,T,E}( + nsamples, system.storages.names, system.timestamps, + storageperiod_mean, period_std, storageperiod_std) + +end + +# GeneratorStorageEnergy + +mutable struct SMCGenStorageEnergyAccumulator <: + ResultAccumulator{SequentialMonteCarlo,GeneratorStorageEnergy} + + # Cross-simulation energy mean/variances + energy_period::Vector{MeanVariance} + energy_genstorperiod::Matrix{MeanVariance} + +end + +function merge!( + x::SMCGenStorageEnergyAccumulator, y::SMCGenStorageEnergyAccumulator +) + + foreach(merge!, x.energy_period, y.energy_period) + foreach(merge!, x.energy_genstorperiod, y.energy_genstorperiod) + + return + +end + +accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageEnergy) = + SMCGenStorageEnergyAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::GeneratorStorageEnergy +) where {N} + + ngenstors = length(sys.generatorstorages) + + energy_period = [meanvariance() for _ in 1:N] + energy_genstorperiod = [meanvariance() for _ in 1:ngenstors, _ in 1:N] + + return SMCGenStorageEnergyAccumulator( + energy_period, energy_genstorperiod) + +end + +function record!( + acc::SMCGenStorageEnergyAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + totalenergy = 0 + ngenstors = length(system.generatorstorages) + + for s in 1:ngenstors + + genstorenergy = state.genstors_energy[s] + fit!(acc.energy_genstorperiod[s,t], genstorenergy) + totalenergy += genstorenergy + + end + + fit!(acc.energy_period[t], totalenergy) + + return + +end + +reset!(acc::SMCGenStorageEnergyAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCGenStorageEnergyAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + _, period_std = mean_std(acc.energy_period) + genstorperiod_mean, genstorperiod_std = mean_std(acc.energy_genstorperiod) + + nsamples = first(first(acc.energy_period).stats).n + + return GeneratorStorageEnergyResult{N,L,T,E}( + nsamples, system.generatorstorages.names, system.timestamps, + genstorperiod_mean, period_std, genstorperiod_std) + +end + +# StorageEnergySamples + +struct SMCStorageEnergySamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,StorageEnergySamples} + + energy::Array{Float64,3} + +end + +function merge!( + x::SMCStorageEnergySamplesAccumulator, y::SMCStorageEnergySamplesAccumulator +) + + x.energy .+= y.energy + return + +end + +accumulatortype(::SequentialMonteCarlo, ::StorageEnergySamples) = + SMCStorageEnergySamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::StorageEnergySamples +) where {N} + + nstors = length(sys.storages) + energy = zeros(Int, nstors, N, simspec.nsamples) + + return SMCStorageEnergySamplesAccumulator(energy) + +end + +function record!( + acc::SMCStorageEnergySamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.energy[:, t, sampleid] .= state.stors_energy + return + +end + +reset!(acc::SMCStorageEnergySamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCStorageEnergySamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return StorageEnergySamplesResult{N,L,T,E}( + system.storages.names, system.timestamps, acc.energy) + +end + +# GeneratorStorageEnergySamples + +struct SMCGenStorageEnergySamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,GeneratorStorageEnergySamples} + + energy::Array{Float64,3} + +end + +function merge!( + x::SMCGenStorageEnergySamplesAccumulator, + y::SMCGenStorageEnergySamplesAccumulator +) + + x.energy .+= y.energy + return + +end + +accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageEnergySamples) = + SMCGenStorageEnergySamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorStorageEnergySamples +) where {N} + + ngenstors = length(sys.generatorstorages) + energy = zeros(Int, ngenstors, N, simspec.nsamples) + + return SMCGenStorageEnergySamplesAccumulator(energy) + +end + +function record!( + acc::SMCGenStorageEnergySamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + acc.energy[:, t, sampleid] .= state.genstors_energy + return + +end + +reset!(acc::SMCGenStorageEnergySamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCGenStorageEnergySamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return GeneratorStorageEnergySamplesResult{N,L,T,E}( + system.generatorstorages.names, system.timestamps, acc.energy) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl new file mode 100644 index 0000000..7e6a7ea --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl @@ -0,0 +1,148 @@ +# Flow + +struct SMCFlowAccumulator <: ResultAccumulator{SequentialMonteCarlo,Flow} + + flow_interface::Vector{MeanVariance} + flow_interfaceperiod::Matrix{MeanVariance} + + flow_interface_currentsim::Vector{Int} + +end + +function merge!( + x::SMCFlowAccumulator, y::SMCFlowAccumulator +) + + foreach(merge!, x.flow_interface, y.flow_interface) + foreach(merge!, x.flow_interfaceperiod, y.flow_interfaceperiod) + +end + +accumulatortype(::SequentialMonteCarlo, ::Flow) = SMCFlowAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::Flow +) where {N} + + n_interfaces = length(sys.interfaces) + flow_interface = [meanvariance() for _ in 1:n_interfaces] + flow_interfaceperiod = [meanvariance() for _ in 1:n_interfaces, _ in 1:N] + + flow_interface_currentsim = zeros(Int, n_interfaces) + + return SMCFlowAccumulator( + flow_interface, flow_interfaceperiod, flow_interface_currentsim) + +end + +function record!( + acc::SMCFlowAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + edges = problem.fp.edges + + for (i, (f, b)) in enumerate(zip(problem.interface_forward_edges, + problem.interface_reverse_edges)) + + flow = edges[f].flow - edges[b].flow + acc.flow_interface_currentsim[i] += flow + fit!(acc.flow_interfaceperiod[i,t], flow) + + end + +end + +function reset!(acc::SMCFlowAccumulator, sampleid::Int) + + for i in eachindex(acc.flow_interface_currentsim) + fit!(acc.flow_interface[i], acc.flow_interface_currentsim[i]) + acc.flow_interface_currentsim[i] = 0 + end + +end + +function finalize( + acc::SMCFlowAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + nsamples = length(system.interfaces) > 0 ? + first(acc.flow_interface[1].stats).n : nothing + + flow_mean, flow_interfaceperiod_std = mean_std(acc.flow_interfaceperiod) + flow_interface_std = last(mean_std(acc.flow_interface)) / N + + fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) + toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) + + return FlowResult{N,L,T,P}( + nsamples, Pair.(fromregions, toregions), system.timestamps, + flow_mean, flow_interface_std, flow_interfaceperiod_std) + +end + +# FlowSamples + +struct SMCFlowSamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,FlowSamples} + + flow::Array{Int,3} + +end + +function merge!( + x::SMCFlowSamplesAccumulator, y::SMCFlowSamplesAccumulator +) + + x.flow .+= y.flow + return + +end + +accumulatortype(::SequentialMonteCarlo, ::FlowSamples) = SMCFlowSamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::FlowSamples +) where {N} + + ninterfaces = length(sys.interfaces) + flow = zeros(Int, ninterfaces, N, simspec.nsamples) + + return SMCFlowSamplesAccumulator(flow) + +end + +function record!( + acc::SMCFlowSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + for (i, (e_f, e_r)) in enumerate(zip(problem.interface_forward_edges, + problem.interface_reverse_edges)) + acc.flow[i, t, sampleid] = problem.fp.edges[e_f].flow - + problem.fp.edges[e_r].flow + end + + return + +end + +reset!(acc::SMCFlowSamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCFlowSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) + toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) + + return FlowSamplesResult{N,L,T,P}( + Pair.(fromregions, toregions), system.timestamps, acc.flow) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl new file mode 100644 index 0000000..0972cc6 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl @@ -0,0 +1,230 @@ +# Shortfall + +mutable struct SMCShortfallAccumulator <: ResultAccumulator{SequentialMonteCarlo,Shortfall} + + # Cross-simulation LOL period count mean/variances + periodsdropped_total::MeanVariance + periodsdropped_region::Vector{MeanVariance} + periodsdropped_period::Vector{MeanVariance} + periodsdropped_regionperiod::Matrix{MeanVariance} + + # Running LOL period counts for current simulation + periodsdropped_total_currentsim::Int + periodsdropped_region_currentsim::Vector{Int} + + # Cross-simulation UE mean/variances + unservedload_total::MeanVariance + unservedload_region::Vector{MeanVariance} + unservedload_period::Vector{MeanVariance} + unservedload_regionperiod::Matrix{MeanVariance} + + # Running UE totals for current simulation + unservedload_total_currentsim::Int + unservedload_region_currentsim::Vector{Int} + +end + +function merge!( + x::SMCShortfallAccumulator, y::SMCShortfallAccumulator +) + + merge!(x.periodsdropped_total, y.periodsdropped_total) + foreach(merge!, x.periodsdropped_region, y.periodsdropped_region) + foreach(merge!, x.periodsdropped_period, y.periodsdropped_period) + foreach(merge!, x.periodsdropped_regionperiod, y.periodsdropped_regionperiod) + + merge!(x.unservedload_total, y.unservedload_total) + foreach(merge!, x.unservedload_region, y.unservedload_region) + foreach(merge!, x.unservedload_period, y.unservedload_period) + foreach(merge!, x.unservedload_regionperiod, y.unservedload_regionperiod) + + return + +end + +accumulatortype(::SequentialMonteCarlo, ::Shortfall) = SMCShortfallAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::Shortfall +) where {N} + + nregions = length(sys.regions) + + periodsdropped_total = meanvariance() + periodsdropped_region = [meanvariance() for _ in 1:nregions] + periodsdropped_period = [meanvariance() for _ in 1:N] + periodsdropped_regionperiod = [meanvariance() for _ in 1:nregions, _ in 1:N] + + periodsdropped_total_currentsim = 0 + periodsdropped_region_currentsim = zeros(Int, nregions) + + unservedload_total = meanvariance() + unservedload_region = [meanvariance() for _ in 1:nregions] + unservedload_period = [meanvariance() for _ in 1:N] + unservedload_regionperiod = [meanvariance() for _ in 1:nregions, _ in 1:N] + + unservedload_total_currentsim = 0 + unservedload_region_currentsim = zeros(Int, nregions) + + return SMCShortfallAccumulator( + periodsdropped_total, periodsdropped_region, + periodsdropped_period, periodsdropped_regionperiod, + periodsdropped_total_currentsim, periodsdropped_region_currentsim, + unservedload_total, unservedload_region, + unservedload_period, unservedload_regionperiod, + unservedload_total_currentsim, unservedload_region_currentsim) + +end + +function record!( + acc::SMCShortfallAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + totalshortfall = 0 + isshortfall = false + + edges = problem.fp.edges + + for r in problem.region_unserved_edges + + regionshortfall = edges[r].flow + isregionshortfall = regionshortfall > 0 + + fit!(acc.periodsdropped_regionperiod[r,t], isregionshortfall) + fit!(acc.unservedload_regionperiod[r,t], regionshortfall) + + if isregionshortfall + + isshortfall = true + totalshortfall += regionshortfall + + acc.periodsdropped_region_currentsim[r] += 1 + acc.unservedload_region_currentsim[r] += regionshortfall + + end + + end + + if isshortfall + acc.periodsdropped_total_currentsim += 1 + acc.unservedload_total_currentsim += totalshortfall + end + + fit!(acc.periodsdropped_period[t], isshortfall) + fit!(acc.unservedload_period[t], totalshortfall) + + return + +end + +function reset!(acc::SMCShortfallAccumulator, sampleid::Int) + + # Store regional / total sums for current simulation + fit!(acc.periodsdropped_total, acc.periodsdropped_total_currentsim) + fit!(acc.unservedload_total, acc.unservedload_total_currentsim) + + for r in eachindex(acc.periodsdropped_region) + fit!(acc.periodsdropped_region[r], acc.periodsdropped_region_currentsim[r]) + fit!(acc.unservedload_region[r], acc.unservedload_region_currentsim[r]) + end + + # Reset for new simulation + acc.periodsdropped_total_currentsim = 0 + fill!(acc.periodsdropped_region_currentsim, 0) + acc.unservedload_total_currentsim = 0 + fill!(acc.unservedload_region_currentsim, 0) + + return + +end + +function finalize( + acc::SMCShortfallAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + ep_total_mean, ep_total_std = mean_std(acc.periodsdropped_total) + ep_region_mean, ep_region_std = mean_std(acc.periodsdropped_region) + ep_period_mean, ep_period_std = mean_std(acc.periodsdropped_period) + ep_regionperiod_mean, ep_regionperiod_std = + mean_std(acc.periodsdropped_regionperiod) + + _, ue_total_std = mean_std(acc.unservedload_total) + _, ue_region_std = mean_std(acc.unservedload_region) + _, ue_period_std = mean_std(acc.unservedload_period) + ue_regionperiod_mean, ue_regionperiod_std = + mean_std(acc.unservedload_regionperiod) + + nsamples = first(acc.unservedload_total.stats).n + p2e = conversionfactor(L,T,P,E) + + return ShortfallResult{N,L,T,E}( + nsamples, system.regions.names, system.timestamps, + ep_total_mean, ep_total_std, ep_region_mean, ep_region_std, + ep_period_mean, ep_period_std, + ep_regionperiod_mean, ep_regionperiod_std, + p2e*ue_regionperiod_mean, p2e*ue_total_std, + p2e*ue_region_std, p2e*ue_period_std, p2e*ue_regionperiod_std) + +end + +# ShortfallSamples + +struct SMCShortfallSamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,ShortfallSamples} + + shortfall::Array{Int,3} + +end + +function merge!( + x::SMCShortfallSamplesAccumulator, y::SMCShortfallSamplesAccumulator +) + + x.shortfall .+= y.shortfall + return + +end + +accumulatortype(::SequentialMonteCarlo, ::ShortfallSamples) = SMCShortfallSamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::ShortfallSamples +) where {N} + + nregions = length(sys.regions) + shortfall = zeros(Int, nregions, N, simspec.nsamples) + + return SMCShortfallSamplesAccumulator(shortfall) + +end + +function record!( + acc::SMCShortfallSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + for (r, e) in enumerate(problem.region_unserved_edges) + acc.shortfall[r, t, sampleid] = problem.fp.edges[e].flow + end + + return + +end + +reset!(acc::SMCShortfallSamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCShortfallSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return ShortfallSamplesResult{N,L,T,P,E}( + system.regions.names, system.timestamps, acc.shortfall) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl new file mode 100644 index 0000000..4386e87 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl @@ -0,0 +1,177 @@ +# Surplus + +mutable struct SMCSurplusAccumulator <: ResultAccumulator{SequentialMonteCarlo,Surplus} + + # Cross-simulation surplus mean/variances + surplus_period::Vector{MeanVariance} + surplus_regionperiod::Matrix{MeanVariance} + +end + +function merge!( + x::SMCSurplusAccumulator, y::SMCSurplusAccumulator +) + + foreach(merge!, x.surplus_period, y.surplus_period) + foreach(merge!, x.surplus_regionperiod, y.surplus_regionperiod) + + return + +end + +accumulatortype(::SequentialMonteCarlo, ::Surplus) = SMCSurplusAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::Surplus +) where {N} + + nregions = length(sys.regions) + + surplus_period = [meanvariance() for _ in 1:N] + surplus_regionperiod = [meanvariance() for _ in 1:nregions, _ in 1:N] + + return SMCSurplusAccumulator( + surplus_period, surplus_regionperiod) + +end + +function record!( + acc::SMCSurplusAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + totalsurplus = 0 + edges = problem.fp.edges + + for (r, e_idx) in enumerate(problem.region_unused_edges) + + regionsurplus = edges[e_idx].flow + + for s in system.region_stor_idxs[r] + se_idx = problem.storage_dischargeunused_edges[s] + regionsurplus += edges[se_idx].flow + end + + for gs in system.region_genstor_idxs[r] + + gse_discharge_idx = problem.genstorage_dischargeunused_edges[gs] + gse_inflow_idx = problem.genstorage_inflowunused_edges[gs] + + grid_limit = system.generatorstorages.gridinjection_capacity[gs, t] + total_unused = edges[gse_discharge_idx].flow + edges[gse_inflow_idx].flow + + regionsurplus += min(grid_limit, total_unused) + + end + + fit!(acc.surplus_regionperiod[r,t], regionsurplus) + totalsurplus += regionsurplus + + end + + fit!(acc.surplus_period[t], totalsurplus) + + return + +end + +reset!(acc::SMCSurplusAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCSurplusAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + _, period_std = mean_std(acc.surplus_period) + regionperiod_mean, regionperiod_std = mean_std(acc.surplus_regionperiod) + + nsamples = first(first(acc.surplus_period).stats).n + + return SurplusResult{N,L,T,P}( + nsamples, system.regions.names, system.timestamps, + regionperiod_mean, period_std, regionperiod_std) + +end + +# SurplusSamples + +struct SMCSurplusSamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,SurplusSamples} + + surplus::Array{Int,3} + +end + +function merge!( + x::SMCSurplusSamplesAccumulator, y::SMCSurplusSamplesAccumulator +) + + x.surplus .+= y.surplus + return + +end + +accumulatortype(::SequentialMonteCarlo, ::SurplusSamples) = SMCSurplusSamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::SurplusSamples +) where {N} + + nregions = length(sys.regions) + surplus = zeros(Int, nregions, N, simspec.nsamples) + + return SMCSurplusSamplesAccumulator(surplus) + +end + +function record!( + acc::SMCSurplusSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + edges = problem.fp.edges + + for (r, e) in enumerate(problem.region_unused_edges) + + regionsurplus = edges[e].flow + + for s in system.region_stor_idxs[r] + se_idx = problem.storage_dischargeunused_edges[s] + regionsurplus += edges[se_idx].flow + end + + for gs in system.region_genstor_idxs[r] + + gse_discharge_idx = problem.genstorage_dischargeunused_edges[gs] + gse_inflow_idx = problem.genstorage_inflowunused_edges[gs] + + grid_limit = system.generatorstorages.gridinjection_capacity[gs, t] + total_unused = edges[gse_discharge_idx].flow + edges[gse_inflow_idx].flow + + regionsurplus += min(grid_limit, total_unused) + + end + + acc.surplus[r, t, sampleid] = regionsurplus + + end + + return + +end + +reset!(acc::SMCSurplusSamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCSurplusSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + return SurplusSamplesResult{N,L,T,P}( + system.regions.names, system.timestamps, acc.surplus) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl new file mode 100644 index 0000000..778cd8c --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl @@ -0,0 +1,173 @@ +# Utilization + +struct SMCUtilizationAccumulator <: ResultAccumulator{SequentialMonteCarlo,Utilization} + + util_interface::Vector{MeanVariance} + util_interfaceperiod::Matrix{MeanVariance} + + util_interface_currentsim::Vector{Float64} + +end + +function merge!( + x::SMCUtilizationAccumulator, y::SMCUtilizationAccumulator +) + + foreach(merge!, x.util_interface, y.util_interface) + foreach(merge!, x.util_interfaceperiod, y.util_interfaceperiod) + +end + +accumulatortype(::SequentialMonteCarlo, ::Utilization) = SMCUtilizationAccumulator + +function accumulator( + sys::SystemModel{N}, ::SequentialMonteCarlo, ::Utilization +) where {N} + + n_interfaces = length(sys.interfaces) + util_interface = [meanvariance() for _ in 1:n_interfaces] + util_interfaceperiod = [meanvariance() for _ in 1:n_interfaces, _ in 1:N] + + util_interface_currentsim = zeros(Int, n_interfaces) + + return SMCUtilizationAccumulator( + util_interface, util_interfaceperiod, util_interface_currentsim) + +end + +function record!( + acc::SMCUtilizationAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + edges = problem.fp.edges + + for (i, (f, b)) in enumerate(zip(problem.interface_forward_edges, + problem.interface_reverse_edges)) + + util = utilization(problem.fp.edges[f], problem.fp.edges[b]) + acc.util_interface_currentsim[i] += util + fit!(acc.util_interfaceperiod[i,t], util) + + end + +end + +function reset!(acc::SMCUtilizationAccumulator, sampleid::Int) + + for i in eachindex(acc.util_interface_currentsim) + fit!(acc.util_interface[i], acc.util_interface_currentsim[i]) + acc.util_interface_currentsim[i] = 0 + end + +end + +function finalize( + acc::SMCUtilizationAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + nsamples = length(system.interfaces) > 0 ? + first(acc.util_interface[1].stats).n : nothing + + util_mean, util_interfaceperiod_std = mean_std(acc.util_interfaceperiod) + util_interface_std = last(mean_std(acc.util_interface)) / N + + fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) + toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) + + return UtilizationResult{N,L,T}( + nsamples, Pair.(fromregions, toregions), system.timestamps, + util_mean, util_interface_std, util_interfaceperiod_std) + +end + +# UtilizationSamples + +struct SMCUtilizationSamplesAccumulator <: + ResultAccumulator{SequentialMonteCarlo,UtilizationSamples} + + utilization::Array{Float64,3} + +end + +function merge!( + x::SMCUtilizationSamplesAccumulator, y::SMCUtilizationSamplesAccumulator +) + + x.utilization .+= y.utilization + return + +end + +accumulatortype(::SequentialMonteCarlo, ::UtilizationSamples) = SMCUtilizationSamplesAccumulator + +function accumulator( + sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::UtilizationSamples +) where {N} + + ninterfaces = length(sys.interfaces) + utilization = zeros(Float64, ninterfaces, N, simspec.nsamples) + + return SMCUtilizationSamplesAccumulator(utilization) + +end + +function record!( + acc::SMCUtilizationSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, + state::SystemState, problem::DispatchProblem, + sampleid::Int, t::Int +) where {N,L,T,P,E} + + for (i, (e_f, e_r)) in enumerate(zip(problem.interface_forward_edges, + problem.interface_reverse_edges)) + + acc.utilization[i, t, sampleid] = + utilization(problem.fp.edges[e_f], problem.fp.edges[e_r]) + + end + + return + +end + +reset!(acc::SMCUtilizationSamplesAccumulator, sampleid::Int) = nothing + +function finalize( + acc::SMCUtilizationSamplesAccumulator, + system::SystemModel{N,L,T,P,E}, +) where {N,L,T,P,E} + + fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) + toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) + + return UtilizationSamplesResult{N,L,T}( + Pair.(fromregions, toregions), system.timestamps, acc.utilization) + +end + + +function utilization(f::MinCostFlows.Edge, b::MinCostFlows.Edge) + + flow_forward = f.flow + max_forward = f.limit + + flow_back = b.flow + max_back = b.limit + + util = if flow_forward > 0 + flow_forward/max_forward + elseif flow_back > 0 + flow_back/max_back + elseif iszero(max_forward) && iszero(max_back) + 1.0 + else + 0.0 + end + + return util + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl new file mode 100644 index 0000000..8bf81bd --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl @@ -0,0 +1,178 @@ +function initialize_availability!( + rng::AbstractRNG, + availability::Vector{Bool}, nexttransition::Vector{Int}, + devices::AbstractAssets, t_last::Int) + + for i in 1:length(devices) + + λ = devices.λ[i, 1] + μ = devices.μ[i, 1] + online = rand(rng) < μ / (λ + μ) + + availability[i] = online + + transitionprobs = online ? devices.λ : devices.μ + nexttransition[i] = randtransitiontime( + rng, transitionprobs, i, 1, t_last) + + end + + return availability + +end + +function update_availability!( + rng::AbstractRNG, + availability::Vector{Bool}, nexttransition::Vector{Int}, + devices::AbstractAssets, t_now::Int, t_last::Int) + + for i in 1:length(devices) + + if nexttransition[i] == t_now # Unit switches states + transitionprobs = (availability[i] ⊻= true) ? devices.λ : devices.μ + nexttransition[i] = randtransitiontime( + rng, transitionprobs, i, t_now, t_last) + end + + end + +end + +function randtransitiontime( + rng::AbstractRNG, p::Matrix{Float64}, + i::Int, t_now::Int, t_last::Int +) + + cdf = 0. + p_noprevtransition = 1. + + x = rand(rng) + t = t_now + 1 + + while t <= t_last + p_it = p[i,t] + cdf += p_noprevtransition * p_it + x < cdf && return t + p_noprevtransition *= (1. - p_it) + t += 1 + end + + return t_last + 1 + +end + +function available_capacity( + availability::Vector{Bool}, + lines::Lines, + idxs::UnitRange{Int}, t::Int +) + + avcap_forward = 0 + avcap_backward = 0 + + for i in idxs + if availability[i] + avcap_forward += lines.forward_capacity[i, t] + avcap_backward += lines.backward_capacity[i, t] + end + end + + return avcap_forward, avcap_backward + +end + +function available_capacity( + availability::Vector{Bool}, + gens::Generators, + idxs::UnitRange{Int}, t::Int +) + + caps = gens.capacity + avcap = 0 + + for i in idxs + availability[i] && (avcap += caps[i, t]) + end + + return avcap + +end + +function update_energy!( + stors_energy::Vector{Int}, + stors::AbstractAssets, + t::Int +) + + for i in 1:length(stors_energy) + + soc = stors_energy[i] + efficiency = stors.carryover_efficiency[i,t] + maxenergy = stors.energy_capacity[i,t] + + # Decay SoC + soc = round(Int, soc * efficiency) + + # Shed SoC above current energy limit + stors_energy[i] = min(soc, maxenergy) + + end + +end + +function maxtimetocharge_discharge(system::SystemModel) + + if length(system.storages) > 0 + + if any(iszero, system.storages.charge_capacity) + stor_charge_max = length(system.timestamps) + 1 + else + stor_charge_durations = + system.storages.energy_capacity ./ system.storages.charge_capacity + stor_charge_max = ceil(Int, maximum(stor_charge_durations)) + end + + if any(iszero, system.storages.discharge_capacity) + stor_discharge_max = length(system.timestamps) + 1 + else + stor_discharge_durations = + system.storages.energy_capacity ./ system.storages.discharge_capacity + stor_discharge_max = ceil(Int, maximum(stor_discharge_durations)) + end + + else + + stor_charge_max = 0 + stor_discharge_max = 0 + + end + + if length(system.generatorstorages) > 0 + + if any(iszero, system.generatorstorages.charge_capacity) + genstor_charge_max = length(system.timestamps) + 1 + else + genstor_charge_durations = + system.generatorstorages.energy_capacity ./ system.generatorstorages.charge_capacity + genstor_charge_max = ceil(Int, maximum(genstor_charge_durations)) + end + + if any(iszero, system.generatorstorages.discharge_capacity) + genstor_discharge_max = length(system.timestamps) + 1 + else + genstor_discharge_durations = + system.generatorstorages.energy_capacity ./ system.generatorstorages.discharge_capacity + genstor_discharge_max = ceil(Int, maximum(genstor_discharge_durations)) + end + + else + + genstor_charge_max = 0 + genstor_discharge_max = 0 + + end + + return (max(stor_charge_max, genstor_charge_max), + max(stor_discharge_max, genstor_discharge_max)) + +end diff --git a/src/PRAS/ResourceAdequacy/simulations/simulations.jl b/src/PRAS/ResourceAdequacy/simulations/simulations.jl new file mode 100644 index 0000000..ba0ccec --- /dev/null +++ b/src/PRAS/ResourceAdequacy/simulations/simulations.jl @@ -0,0 +1,4 @@ +broadcastable(x::SimulationSpec) = Ref(x) + +include("convolution/Convolution.jl") +include("sequentialmontecarlo/SequentialMonteCarlo.jl") diff --git a/src/PRAS/ResourceAdequacy/utils.jl b/src/PRAS/ResourceAdequacy/utils.jl new file mode 100644 index 0000000..4fc10a0 --- /dev/null +++ b/src/PRAS/ResourceAdequacy/utils.jl @@ -0,0 +1,54 @@ +meanvariance() = Series(Mean(), Variance()) + +function mean_std(x::MeanVariance) + m, v = value(x) + return m, sqrt(v) +end + +function mean_std(x::AbstractArray{<:MeanVariance}) + + means = similar(x, Float64) + vars = similar(means) + + for i in eachindex(x) + m, v = mean_std(x[i]) + means[i] = m + vars[i] = v + end + + return means, vars + +end + +function findfirstunique_directional(a::AbstractVector{<:Pair}, i::Pair) + i_idx = findfirst(isequal(i), a) + if isnothing(i_idx) + i_idx = findfirstunique(a, last(i) => first(i)) + reverse = true + else + reverse = false + end + return i_idx, reverse +end + +function findfirstunique(a::AbstractVector{T}, i::T) where T + i_idx = findfirst(isequal(i), a) + i_idx === nothing && throw(BoundsError(a)) + return i_idx +end + +function assetgrouplist(idxss::Vector{UnitRange{Int}}) + results = Vector{Int}(undef, last(idxss[end])) + for (g, idxs) in enumerate(idxss) + results[idxs] .= g + end + return results +end + +function colsum(x::Matrix{T}, col::Int) where {T} + result = zero(T) + for i in 1:size(x, 1) + result += x[i, col] + end + return result +end From 233eebbad11c1dd4304d1d492b3bcf3ea5fad311 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 31 Oct 2024 16:16:34 -0600 Subject: [PATCH 2/2] format pras --- src/PRAS/CapacityCredit/CapacityCredit.jl | 6 +- .../CapacityCredit/CapacityCreditResult.jl | 22 +- src/PRAS/CapacityCredit/EFC.jl | 124 ++++---- src/PRAS/CapacityCredit/ELCC.jl | 90 +++--- src/PRAS/CapacityCredit/utils.jl | 15 +- src/PRAS/LICENSE.md | 23 ++ src/PRAS/PRAS.jl | 2 +- src/PRAS/PRASBase/PRASBase.jl | 63 ++++- src/PRAS/PRASBase/SystemModel.jl | 154 +++++----- src/PRAS/PRASBase/assets.jl | 266 +++++++++++------- src/PRAS/PRASBase/collections.jl | 37 +-- src/PRAS/PRASBase/read.jl | 204 +++++++------- src/PRAS/PRASBase/units.jl | 45 +-- src/PRAS/PRASBase/utils.jl | 16 +- src/PRAS/PRASBase/write.jl | 184 +++++------- src/PRAS/ResourceAdequacy/ResourceAdequacy.jl | 43 ++- src/PRAS/ResourceAdequacy/metrics.jl | 80 +++--- .../ResourceAdequacy/results/availability.jl | 41 ++- src/PRAS/ResourceAdequacy/results/energy.jl | 53 ++-- src/PRAS/ResourceAdequacy/results/flow.jl | 47 ++-- src/PRAS/ResourceAdequacy/results/results.jl | 19 +- .../ResourceAdequacy/results/shortfall.jl | 224 ++++++++------- src/PRAS/ResourceAdequacy/results/surplus.jl | 25 +- .../ResourceAdequacy/results/utilization.jl | 51 ++-- .../simulations/convolution/Convolution.jl | 27 +- .../simulations/convolution/conv.jl | 76 +++-- .../convolution/result_shortfall.jl | 47 ++-- .../simulations/convolution/result_surplus.jl | 33 +-- .../sequentialmontecarlo/DispatchProblem.jl | 200 ++++++------- .../SequentialMonteCarlo.jl | 139 +++++---- .../sequentialmontecarlo/SystemState.jl | 21 +- .../result_availability.jl | 181 ++++++------ .../sequentialmontecarlo/result_energy.jl | 185 ++++++------ .../sequentialmontecarlo/result_flow.jl | 115 ++++---- .../sequentialmontecarlo/result_shortfall.jl | 139 +++++---- .../sequentialmontecarlo/result_surplus.jl | 100 +++---- .../result_utilization.jl | 123 ++++---- .../simulations/sequentialmontecarlo/utils.jl | 90 +++--- src/PRAS/ResourceAdequacy/utils.jl | 4 +- 39 files changed, 1689 insertions(+), 1625 deletions(-) create mode 100644 src/PRAS/LICENSE.md diff --git a/src/PRAS/CapacityCredit/CapacityCredit.jl b/src/PRAS/CapacityCredit/CapacityCredit.jl index 4942645..0fd2d8d 100644 --- a/src/PRAS/CapacityCredit/CapacityCredit.jl +++ b/src/PRAS/CapacityCredit/CapacityCredit.jl @@ -3,12 +3,12 @@ import Base: minimum, maximum, extrema import Distributions: ccdf, Normal import ..PRASBase: Generators, PowerUnit, Regions, SystemModel, unitsymbol -import ..ResourceAdequacy: assess, ReliabilityMetric, Result, Shortfall, - SimulationSpec, stderror, val +import ..ResourceAdequacy: + assess, ReliabilityMetric, Result, Shortfall, SimulationSpec, stderror, val export EFC, ELCC -abstract type CapacityValuationMethod{M<:ReliabilityMetric} end +abstract type CapacityValuationMethod{M <: ReliabilityMetric} end include("utils.jl") include("CapacityCreditResult.jl") diff --git a/src/PRAS/CapacityCredit/CapacityCreditResult.jl b/src/PRAS/CapacityCredit/CapacityCreditResult.jl index aeeec9b..2f42cd2 100644 --- a/src/PRAS/CapacityCredit/CapacityCreditResult.jl +++ b/src/PRAS/CapacityCredit/CapacityCreditResult.jl @@ -1,24 +1,26 @@ struct CapacityCreditResult{ - S <: CapacityValuationMethod, M <: ReliabilityMetric, P <: PowerUnit} - + S <: CapacityValuationMethod, + M <: ReliabilityMetric, + P <: PowerUnit, +} target_metric::M lowerbound::Int upperbound::Int bound_capacities::Vector{Int} bound_metrics::Vector{M} - function CapacityCreditResult{S,M,P}( - target_metric::M, lowerbound::Int, upperbound::Int, - bound_capacities::Vector{Int}, bound_metrics::Vector{M}) where {S,M,P} - + function CapacityCreditResult{S, M, P}( + target_metric::M, + lowerbound::Int, + upperbound::Int, + bound_capacities::Vector{Int}, + bound_metrics::Vector{M}, + ) where {S, M, P} length(bound_capacities) == length(bound_metrics) || throw(ArgumentError("Lengths of bound_capacities and bound_metrics must match")) - new{S,M,P}(target_metric, lowerbound, upperbound, - bound_capacities, bound_metrics) - + new{S, M, P}(target_metric, lowerbound, upperbound, bound_capacities, bound_metrics) end - end minimum(x::CapacityCreditResult) = x.lowerbound diff --git a/src/PRAS/CapacityCredit/EFC.jl b/src/PRAS/CapacityCredit/EFC.jl index 2ff9f12..0676ba3 100644 --- a/src/PRAS/CapacityCredit/EFC.jl +++ b/src/PRAS/CapacityCredit/EFC.jl @@ -1,36 +1,36 @@ struct EFC{M} <: CapacityValuationMethod{M} - capacity_max::Int capacity_gap::Int p_value::Float64 - regions::Vector{Tuple{String,Float64}} + regions::Vector{Tuple{String, Float64}} verbose::Bool function EFC{M}( - capacity_max::Int, regions::Vector{Pair{String,Float64}}; - capacity_gap::Int=1, p_value::Float64=0.05, verbose::Bool=false) where M - + capacity_max::Int, + regions::Vector{Pair{String, Float64}}; + capacity_gap::Int=1, + p_value::Float64=0.05, + verbose::Bool=false, + ) where {M} @assert capacity_max > 0 @assert capacity_gap > 0 @assert 0 < p_value < 1 @assert sum(x.second for x in regions) ≈ 1.0 return new{M}(capacity_max, capacity_gap, p_value, Tuple.(regions), verbose) - end - end -function EFC{M}( - capacity_max::Int, region::String; kwargs... -) where M - return EFC{M}(capacity_max, [region=>1.0]; kwargs...) +function EFC{M}(capacity_max::Int, region::String; kwargs...) where {M} + return EFC{M}(capacity_max, [region => 1.0]; kwargs...) end -function assess(sys_baseline::S, sys_augmented::S, - params::EFC{M}, simulationspec::SimulationSpec -) where {N, L, T, P, S <: SystemModel{N,L,T,P}, M <: ReliabilityMetric} - +function assess( + sys_baseline::S, + sys_augmented::S, + params::EFC{M}, + simulationspec::SimulationSpec, +) where {N, L, T, P, S <: SystemModel{N, L, T, P}, M <: ReliabilityMetric} _, powerunit, _ = unitsymbol(sys_baseline) regionnames = sys_baseline.regions.names @@ -58,10 +58,10 @@ function assess(sys_baseline::S, sys_augmented::S, push!(metrics, upper_bound_metric) while true - params.verbose && println( "\n$(lower_bound) $powerunit\t< EFC <\t$(upper_bound) $powerunit\n", - "$(lower_bound_metric)\t> $(target_metric) >\t$(upper_bound_metric)") + "$(lower_bound_metric)\t> $(target_metric) >\t$(upper_bound_metric)", + ) midpoint = div(lower_bound + upper_bound, 2) capacity_gap = upper_bound - lower_bound @@ -70,7 +70,8 @@ function assess(sys_baseline::S, sys_augmented::S, ## Return the bounds if they are within solution tolerance of each other if capacity_gap <= params.capacity_gap - params.verbose && @info "Capacity bound gap within tolerance, stopping bisection." + params.verbose && + @info "Capacity bound gap within tolerance, stopping bisection." break end @@ -99,30 +100,37 @@ function assess(sys_baseline::S, sys_augmented::S, upper_bound = midpoint upper_bound_metric = midpoint_metric end - end return CapacityCreditResult{typeof(params), typeof(target_metric), P}( - target_metric, lower_bound, upper_bound, capacities, metrics) - + target_metric, + lower_bound, + upper_bound, + capacities, + metrics, + ) end function add_firmcapacity( - s1::SystemModel{N,L,T,P,E}, s2::SystemModel{N,L,T,P,E}, - region_shares::Vector{Tuple{String,Float64}} -) where {N,L,T,P,E} - + s1::SystemModel{N, L, T, P, E}, + s2::SystemModel{N, L, T, P, E}, + region_shares::Vector{Tuple{String, Float64}}, +) where {N, L, T, P, E} n_regions = length(s1.regions.names) n_region_allocs = length(region_shares) region_allocations = allocate_regions(s1.regions.names, region_shares) efc_gens = similar(region_allocations) - new_gen(i::Int) = Generators{N,L,T,P}( - ["_EFC_$i"], ["_EFC Calculation Dummy Generator"], - zeros(Int, 1, N), zeros(1, N), ones(1, N)) + new_gen(i::Int) = Generators{N, L, T, P}( + ["_EFC_$i"], + ["_EFC Calculation Dummy Generator"], + zeros(Int, 1, N), + zeros(1, N), + ones(1, N), + ) - variable_gens = Generators{N,L,T,P}[] + variable_gens = Generators{N, L, T, P}[] variable_region_gen_idxs = similar(s1.region_gen_idxs) target_gens = similar(variable_gens) @@ -131,59 +139,67 @@ function add_firmcapacity( ra_idx = 0 for r in 1:n_regions - s1_range = s1.region_gen_idxs[r] s2_range = s2.region_gen_idxs[r] - if (ra_idx < n_region_allocs) && (r == first(region_allocations[ra_idx+1])) - + if (ra_idx < n_region_allocs) && (r == first(region_allocations[ra_idx + 1])) ra_idx += 1 - variable_region_gen_idxs[r] = incr_range(s1_range, ra_idx-1, ra_idx) - target_region_gen_idxs[r] = incr_range(s2_range, ra_idx-1, ra_idx) + variable_region_gen_idxs[r] = incr_range(s1_range, ra_idx - 1, ra_idx) + target_region_gen_idxs[r] = incr_range(s2_range, ra_idx - 1, ra_idx) gen = new_gen(ra_idx) push!(variable_gens, gen) push!(target_gens, gen) - efc_gens[ra_idx] = ( - first(s1_range) + ra_idx - 1, - last(region_allocations[ra_idx])) + efc_gens[ra_idx] = + (first(s1_range) + ra_idx - 1, last(region_allocations[ra_idx])) else - variable_region_gen_idxs[r] = incr_range(s1_range, ra_idx) target_region_gen_idxs[r] = incr_range(s2_range, ra_idx) - end push!(variable_gens, s1.generators[s1_range]) push!(target_gens, s2.generators[s2_range]) - end sys_variable = SystemModel( - s1.regions, s1.interfaces, - vcat(variable_gens...), variable_region_gen_idxs, - s1.storages, s1.region_stor_idxs, - s1.generatorstorages, s1.region_genstor_idxs, - s1.lines, s1.interface_line_idxs, s1.timestamps) + s1.regions, + s1.interfaces, + vcat(variable_gens...), + variable_region_gen_idxs, + s1.storages, + s1.region_stor_idxs, + s1.generatorstorages, + s1.region_genstor_idxs, + s1.lines, + s1.interface_line_idxs, + s1.timestamps, + ) sys_target = SystemModel( - s2.regions, s2.interfaces, - vcat(target_gens...), target_region_gen_idxs, - s2.storages, s2.region_stor_idxs, - s2.generatorstorages, s2.region_genstor_idxs, - s2.lines, s2.interface_line_idxs, s2.timestamps) + s2.regions, + s2.interfaces, + vcat(target_gens...), + target_region_gen_idxs, + s2.storages, + s2.region_stor_idxs, + s2.generatorstorages, + s2.region_genstor_idxs, + s2.lines, + s2.interface_line_idxs, + s2.timestamps, + ) return efc_gens, sys_variable, sys_target - end function update_firmcapacity!( - sys::SystemModel, gens::Vector{Tuple{Int,Float64}}, capacity::Int) - + sys::SystemModel, + gens::Vector{Tuple{Int, Float64}}, + capacity::Int, +) for (g, share) in gens sys.generators.capacity[g, :] .= round(Int, share * capacity) end - end diff --git a/src/PRAS/CapacityCredit/ELCC.jl b/src/PRAS/CapacityCredit/ELCC.jl index 746290e..5f50688 100644 --- a/src/PRAS/CapacityCredit/ELCC.jl +++ b/src/PRAS/CapacityCredit/ELCC.jl @@ -1,36 +1,36 @@ struct ELCC{M} <: CapacityValuationMethod{M} - capacity_max::Int capacity_gap::Int p_value::Float64 - regions::Vector{Tuple{String,Float64}} + regions::Vector{Tuple{String, Float64}} verbose::Bool function ELCC{M}( - capacity_max::Int, regions::Vector{Pair{String,Float64}}; - capacity_gap::Int=1, p_value::Float64=0.05, verbose::Bool=false) where M - + capacity_max::Int, + regions::Vector{Pair{String, Float64}}; + capacity_gap::Int=1, + p_value::Float64=0.05, + verbose::Bool=false, + ) where {M} @assert capacity_max > 0 @assert capacity_gap > 0 @assert 0 < p_value < 1 @assert sum(x.second for x in regions) ≈ 1.0 return new{M}(capacity_max, capacity_gap, p_value, Tuple.(regions), verbose) - end - end -function ELCC{M}( - capacity_max::Int, region::String; kwargs... -) where M - return ELCC{M}(capacity_max, [region=>1.0]; kwargs...) +function ELCC{M}(capacity_max::Int, region::String; kwargs...) where {M} + return ELCC{M}(capacity_max, [region => 1.0]; kwargs...) end -function assess(sys_baseline::S, sys_augmented::S, - params::ELCC{M}, simulationspec::SimulationSpec -) where {N, L, T, P, S <: SystemModel{N,L,T,P}, M <: ReliabilityMetric} - +function assess( + sys_baseline::S, + sys_augmented::S, + params::ELCC{M}, + simulationspec::SimulationSpec, +) where {N, L, T, P, S <: SystemModel{N, L, T, P}, M <: ReliabilityMetric} _, powerunit, _ = unitsymbol(sys_baseline) regionnames = sys_baseline.regions.names @@ -42,8 +42,7 @@ function assess(sys_baseline::S, sys_augmented::S, capacities = Int[] metrics = typeof(target_metric)[] - elcc_regions, base_load, sys_variable = - copy_load(sys_augmented, params.regions) + elcc_regions, base_load, sys_variable = copy_load(sys_augmented, params.regions) lower_bound = 0 lower_bound_metric = M(first(assess(sys_variable, simulationspec, Shortfall()))) @@ -57,10 +56,10 @@ function assess(sys_baseline::S, sys_augmented::S, push!(metrics, upper_bound_metric) while true - params.verbose && println( "\n$(lower_bound) $powerunit\t< ELCC <\t$(upper_bound) $powerunit\n", - "$(lower_bound_metric)\t< $(target_metric) <\t$(upper_bound_metric)") + "$(lower_bound_metric)\t< $(target_metric) <\t$(upper_bound_metric)", + ) midpoint = div(lower_bound + upper_bound, 2) capacity_gap = upper_bound - lower_bound @@ -69,7 +68,8 @@ function assess(sys_baseline::S, sys_augmented::S, ## Return the bounds if they are within solution tolerance of each other if capacity_gap <= params.capacity_gap - params.verbose && @info "Capacity bound gap within tolerance, stopping bisection." + params.verbose && + @info "Capacity bound gap within tolerance, stopping bisection." break end @@ -98,41 +98,49 @@ function assess(sys_baseline::S, sys_augmented::S, upper_bound = midpoint upper_bound_metric = midpoint_metric end - end return CapacityCreditResult{typeof(params), typeof(target_metric), P}( - target_metric, lower_bound, upper_bound, capacities, metrics) - + target_metric, + lower_bound, + upper_bound, + capacities, + metrics, + ) end function copy_load( - sys::SystemModel{N,L,T,P,E}, - region_shares::Vector{Tuple{String,Float64}} -) where {N,L,T,P,E} - + sys::SystemModel{N, L, T, P, E}, + region_shares::Vector{Tuple{String, Float64}}, +) where {N, L, T, P, E} region_allocations = allocate_regions(sys.regions.names, region_shares) - new_regions = Regions{N,P}(sys.regions.names, copy(sys.regions.load)) - - return region_allocations, sys.regions.load, SystemModel( - new_regions, sys.interfaces, - sys.generators, sys.region_gen_idxs, - sys.storages, sys.region_stor_idxs, - sys.generatorstorages, sys.region_genstor_idxs, - sys.lines, sys.interface_line_idxs, sys.timestamps) - + new_regions = Regions{N, P}(sys.regions.names, copy(sys.regions.load)) + + return region_allocations, + sys.regions.load, + SystemModel( + new_regions, + sys.interfaces, + sys.generators, + sys.region_gen_idxs, + sys.storages, + sys.region_stor_idxs, + sys.generatorstorages, + sys.region_genstor_idxs, + sys.lines, + sys.interface_line_idxs, + sys.timestamps, + ) end function update_load!( sys::SystemModel, - region_shares::Vector{Tuple{Int,Float64}}, + region_shares::Vector{Tuple{Int, Float64}}, load_base::Matrix{Int}, - load_increase::Int + load_increase::Int, ) for (r, share) in region_shares - sys.regions.load[r, :] .= load_base[r, :] .+ - round(Int, share * load_increase) + sys.regions.load[r, :] .= load_base[r, :] .+ round(Int, share * load_increase) end - end diff --git a/src/PRAS/CapacityCredit/utils.jl b/src/PRAS/CapacityCredit/utils.jl index 2f09a4a..b765188 100644 --- a/src/PRAS/CapacityCredit/utils.jl +++ b/src/PRAS/CapacityCredit/utils.jl @@ -1,5 +1,4 @@ -function pvalue(lower::T, upper::T) where {T<:ReliabilityMetric} - +function pvalue(lower::T, upper::T) where {T <: ReliabilityMetric} vl = val(lower) sl = stderror(lower) @@ -15,29 +14,23 @@ function pvalue(lower::T, upper::T) where {T<:ReliabilityMetric} end return result - end function allocate_regions( region_names::Vector{String}, - regionname_shares::Vector{Tuple{String,Float64}} + regionname_shares::Vector{Tuple{String, Float64}}, ) - - region_allocations = similar(regionname_shares, Tuple{Int,Float64}) + region_allocations = similar(regionname_shares, Tuple{Int, Float64}) for (i, (name, share)) in enumerate(regionname_shares) - r = findfirst(isequal(name), region_names) - isnothing(r) && - error("$name is not a region name in the provided systems") + isnothing(r) && error("$name is not a region name in the provided systems") region_allocations[i] = (r, share) - end return sort!(region_allocations) - end incr_range(rnge::UnitRange{Int}, inc::Int) = rnge .+ inc diff --git a/src/PRAS/LICENSE.md b/src/PRAS/LICENSE.md new file mode 100644 index 0000000..61effd7 --- /dev/null +++ b/src/PRAS/LICENSE.md @@ -0,0 +1,23 @@ +The PRAS package is licensed under a modified MIT "Expat" License: + +> Copyright 2020 Alliance for Sustainable Energy, LLC +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS, THE COPYRIGHT HOLDERS, THE UNITED STATES, THE UNITED STATES DEPARTMENT +> OF ENERGY, OR ANY OF THEIR EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> diff --git a/src/PRAS/PRAS.jl b/src/PRAS/PRAS.jl index c5e729f..8093d33 100644 --- a/src/PRAS/PRAS.jl +++ b/src/PRAS/PRAS.jl @@ -8,6 +8,6 @@ include("PRASBase/PRASBase.jl") include("ResourceAdequacy/ResourceAdequacy.jl") include("CapacityCredit/CapacityCredit.jl") -import .PRASBase: rts_gmlc,toymodel +import .PRASBase: rts_gmlc, toymodel end diff --git a/src/PRAS/PRASBase/PRASBase.jl b/src/PRAS/PRASBase/PRASBase.jl index 75e9f97..7d301fc 100644 --- a/src/PRAS/PRASBase/PRASBase.jl +++ b/src/PRAS/PRASBase/PRASBase.jl @@ -4,31 +4,68 @@ import ..PRAS_VERSION import Base: broadcastable -import Dates: @dateformat_str, AbstractDateTime, DateTime, - Period, Minute, Hour, Day, Year +import Dates: @dateformat_str, AbstractDateTime, DateTime, Period, Minute, Hour, Day, Year -import HDF5: HDF5, attributes, File, Group, Dataset, Datatype, dataspace, - h5open, create_group, create_dataset, hdf5_type_id +import HDF5: + HDF5, + attributes, + File, + Group, + Dataset, + Datatype, + dataspace, + h5open, + create_group, + create_dataset, + hdf5_type_id -import HDF5.API: h5t_create, h5t_copy, h5t_insert, h5t_set_size, H5T_COMPOUND, - h5d_write, H5S_ALL, H5P_DEFAULT +import HDF5.API: + h5t_create, + h5t_copy, + h5t_insert, + h5t_set_size, + H5T_COMPOUND, + h5d_write, + H5S_ALL, + H5P_DEFAULT import TimeZones: TimeZone, ZonedDateTime export # System assets - Regions, Interfaces, - AbstractAssets, Generators, Storages, GeneratorStorages, Lines, + Regions, + Interfaces, + AbstractAssets, + Generators, + Storages, + GeneratorStorages, + Lines, # Units - Period, Minute, Hour, Day, Year, - PowerUnit, kW, MW, GW, TW, - EnergyUnit, kWh, MWh, GWh, TWh, - unitsymbol, conversionfactor, powertoenergy, energytopower, + Period, + Minute, + Hour, + Day, + Year, + PowerUnit, + kW, + MW, + GW, + TW, + EnergyUnit, + kWh, + MWh, + GWh, + TWh, + unitsymbol, + conversionfactor, + powertoenergy, + energytopower, # Main data structure - SystemModel, savemodel + SystemModel, + savemodel include("units.jl") include("collections.jl") diff --git a/src/PRAS/PRASBase/SystemModel.jl b/src/PRAS/PRASBase/SystemModel.jl index 119c465..222dbed 100644 --- a/src/PRAS/PRASBase/SystemModel.jl +++ b/src/PRAS/PRASBase/SystemModel.jl @@ -1,32 +1,34 @@ -struct SystemModel{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} +struct SystemModel{N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} + regions::Regions{N, P} + interfaces::Interfaces{N, P} - regions::Regions{N,P} - interfaces::Interfaces{N,P} - - generators::Generators{N,L,T,P} + generators::Generators{N, L, T, P} region_gen_idxs::Vector{UnitRange{Int}} - storages::Storages{N,L,T,P,E} + storages::Storages{N, L, T, P, E} region_stor_idxs::Vector{UnitRange{Int}} - generatorstorages::GeneratorStorages{N,L,T,P,E} + generatorstorages::GeneratorStorages{N, L, T, P, E} region_genstor_idxs::Vector{UnitRange{Int}} - lines::Lines{N,L,T,P} + lines::Lines{N, L, T, P} interface_line_idxs::Vector{UnitRange{Int}} - timestamps::StepRange{ZonedDateTime,T} + timestamps::StepRange{ZonedDateTime, T} function SystemModel{}( - regions::Regions{N,P}, interfaces::Interfaces{N,P}, - generators::Generators{N,L,T,P}, region_gen_idxs::Vector{UnitRange{Int}}, - storages::Storages{N,L,T,P,E}, region_stor_idxs::Vector{UnitRange{Int}}, - generatorstorages::GeneratorStorages{N,L,T,P,E}, + regions::Regions{N, P}, + interfaces::Interfaces{N, P}, + generators::Generators{N, L, T, P}, + region_gen_idxs::Vector{UnitRange{Int}}, + storages::Storages{N, L, T, P, E}, + region_stor_idxs::Vector{UnitRange{Int}}, + generatorstorages::GeneratorStorages{N, L, T, P, E}, region_genstor_idxs::Vector{UnitRange{Int}}, - lines::Lines{N,L,T,P}, interface_line_idxs::Vector{UnitRange{Int}}, - timestamps::StepRange{ZonedDateTime,T} - ) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} - + lines::Lines{N, L, T, P}, + interface_line_idxs::Vector{UnitRange{Int}}, + timestamps::StepRange{ZonedDateTime, T}, + ) where {N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} n_regions = length(regions) n_gens = length(generators) n_stors = length(storages) @@ -41,32 +43,43 @@ struct SystemModel{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} @assert consistent_idxs(interface_line_idxs, n_lines, n_interfaces) @assert all( - 1 <= interfaces.regions_from[i] < interfaces.regions_to[i] <= n_regions - for i in 1:n_interfaces) + 1 <= interfaces.regions_from[i] < interfaces.regions_to[i] <= n_regions for + i in 1:n_interfaces + ) @assert step(timestamps) == T(L) @assert length(timestamps) == N - new{N,L,T,P,E}( - regions, interfaces, - generators, region_gen_idxs, storages, region_stor_idxs, - generatorstorages, region_genstor_idxs, lines, interface_line_idxs, - timestamps) - + new{N, L, T, P, E}( + regions, + interfaces, + generators, + region_gen_idxs, + storages, + region_stor_idxs, + generatorstorages, + region_genstor_idxs, + lines, + interface_line_idxs, + timestamps, + ) end - end # No time zone constructor function SystemModel( - regions::Regions{N,P}, interfaces::Interfaces{N,P}, - generators::Generators{N,L,T,P}, region_gen_idxs::Vector{UnitRange{Int}}, - storages::Storages{N,L,T,P,E}, region_stor_idxs::Vector{UnitRange{Int}}, - generatorstorages::GeneratorStorages{N,L,T,P,E}, region_genstor_idxs::Vector{UnitRange{Int}}, - lines, interface_line_idxs::Vector{UnitRange{Int}}, - timestamps::StepRange{DateTime,T} -) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} - + regions::Regions{N, P}, + interfaces::Interfaces{N, P}, + generators::Generators{N, L, T, P}, + region_gen_idxs::Vector{UnitRange{Int}}, + storages::Storages{N, L, T, P, E}, + region_stor_idxs::Vector{UnitRange{Int}}, + generatorstorages::GeneratorStorages{N, L, T, P, E}, + region_genstor_idxs::Vector{UnitRange{Int}}, + lines, + interface_line_idxs::Vector{UnitRange{Int}}, + timestamps::StepRange{DateTime, T}, +) where {N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} @warn "No time zone data provided - defaulting to UTC. To specify a " * "time zone for the system timestamps, provide a range of " * "`ZonedDateTime` instead of `DateTime`." @@ -77,38 +90,48 @@ function SystemModel( timestamps_tz = time_start:step(timestamps):time_end return SystemModel( - regions, interfaces, - generators, region_gen_idxs, - storages, region_stor_idxs, - generatorstorages, region_genstor_idxs, - lines, interface_line_idxs, - timestamps_tz) - + regions, + interfaces, + generators, + region_gen_idxs, + storages, + region_stor_idxs, + generatorstorages, + region_genstor_idxs, + lines, + interface_line_idxs, + timestamps_tz, + ) end # Single-node constructor function SystemModel( - generators::Generators{N,L,T,P}, - storages::Storages{N,L,T,P,E}, - generatorstorages::GeneratorStorages{N,L,T,P,E}, - timestamps::StepRange{<:AbstractDateTime,T}, - load::Vector{Int} -) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} - + generators::Generators{N, L, T, P}, + storages::Storages{N, L, T, P, E}, + generatorstorages::GeneratorStorages{N, L, T, P, E}, + timestamps::StepRange{<:AbstractDateTime, T}, + load::Vector{Int}, +) where {N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} return SystemModel( - Regions{N,P}(["Region"], reshape(load, 1, :)), - Interfaces{N,P}( - Int[], Int[], - Matrix{Int}(undef, 0, N), Matrix{Int}(undef, 0, N)), - generators, [1:length(generators)], - storages, [1:length(storages)], - generatorstorages, [1:length(generatorstorages)], - Lines{N,L,T,P}( - String[], String[], - Matrix{Int}(undef, 0, N), Matrix{Int}(undef, 0, N), - Matrix{Float64}(undef, 0, N), Matrix{Float64}(undef, 0, N)), - UnitRange{Int}[], timestamps) - + Regions{N, P}(["Region"], reshape(load, 1, :)), + Interfaces{N, P}(Int[], Int[], Matrix{Int}(undef, 0, N), Matrix{Int}(undef, 0, N)), + generators, + [1:length(generators)], + storages, + [1:length(storages)], + generatorstorages, + [1:length(generatorstorages)], + Lines{N, L, T, P}( + String[], + String[], + Matrix{Int}(undef, 0, N), + Matrix{Int}(undef, 0, N), + Matrix{Float64}(undef, 0, N), + Matrix{Float64}(undef, 0, N), + ), + UnitRange{Int}[], + timestamps, + ) end Base.:(==)(x::T, y::T) where {T <: SystemModel} = @@ -126,12 +149,12 @@ Base.:(==)(x::T, y::T) where {T <: SystemModel} = broadcastable(x::SystemModel) = Ref(x) -unitsymbol(::SystemModel{N,L,T,P,E}) where { - N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} = +unitsymbol( + ::SystemModel{N, L, T, P, E}, +) where {N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} = unitsymbol(T), unitsymbol(P), unitsymbol(E) function consistent_idxs(idxss::Vector{UnitRange{Int}}, nitems::Int, ngroups::Int) - length(idxss) == ngroups || return false expected_next = 1 @@ -142,7 +165,6 @@ function consistent_idxs(idxss::Vector{UnitRange{Int}}, nitems::Int, ngroups::In expected_next == nitems + 1 || return false return true - end function rts_gmlc() @@ -153,4 +175,4 @@ end function toymodel() path = dirname(@__FILE__) return SystemModel(path * "/toymodel.pras") -end \ No newline at end of file +end diff --git a/src/PRAS/PRASBase/assets.jl b/src/PRAS/PRASBase/assets.jl index 14c13d1..4cd20fe 100644 --- a/src/PRAS/PRASBase/assets.jl +++ b/src/PRAS/PRASBase/assets.jl @@ -1,8 +1,7 @@ -abstract type AbstractAssets{N,L,T<:Period,P<:PowerUnit} end +abstract type AbstractAssets{N, L, T <: Period, P <: PowerUnit} end Base.length(a::AbstractAssets) = length(a.names) -struct Generators{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} - +struct Generators{N, L, T <: Period, P <: PowerUnit} <: AbstractAssets{N, L, T, P} names::Vector{String} categories::Vector{String} @@ -11,11 +10,13 @@ struct Generators{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} λ::Matrix{Float64} μ::Matrix{Float64} - function Generators{N,L,T,P}( - names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, - capacity::Matrix{Int}, λ::Matrix{Float64}, μ::Matrix{Float64} - ) where {N,L,T,P} - + function Generators{N, L, T, P}( + names::Vector{<:AbstractString}, + categories::Vector{<:AbstractString}, + capacity::Matrix{Int}, + λ::Matrix{Float64}, + μ::Matrix{Float64}, + ) where {N, L, T, P} n_gens = length(names) @assert length(categories) == n_gens @assert allunique(names) @@ -28,10 +29,8 @@ struct Generators{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} @assert all(0 .<= λ .<= 1) @assert all(0 .<= μ .<= 1) - new{N,L,T,P}(string.(names), string.(categories), capacity, λ, μ) - + new{N, L, T, P}(string.(names), string.(categories), capacity, λ, μ) end - end Base.:(==)(x::T, y::T) where {T <: Generators} = @@ -42,11 +41,9 @@ Base.:(==)(x::T, y::T) where {T <: Generators} = x.μ == y.μ Base.getindex(g::G, idxs::AbstractVector{Int}) where {G <: Generators} = - G(g.names[idxs], g.categories[idxs], - g.capacity[idxs, :], g.λ[idxs, :], g.μ[idxs, :]) - -function Base.vcat(gs::Generators{N,L,T,P}...) where {N, L, T, P} + G(g.names[idxs], g.categories[idxs], g.capacity[idxs, :], g.λ[idxs, :], g.μ[idxs, :]) +function Base.vcat(gs::Generators{N, L, T, P}...) where {N, L, T, P} n_gens = sum(length(g) for g in gs) names = Vector{String}(undef, n_gens) @@ -60,7 +57,6 @@ function Base.vcat(gs::Generators{N,L,T,P}...) where {N, L, T, P} last_idx = 0 for g in gs - n = length(g) rows = last_idx .+ (1:n) @@ -71,15 +67,13 @@ function Base.vcat(gs::Generators{N,L,T,P}...) where {N, L, T, P} μ[rows, :] = g.μ last_idx += n - end - return Generators{N,L,T,P}(names, categories, capacity, λ, μ) - + return Generators{N, L, T, P}(names, categories, capacity, λ, μ) end -struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P} - +struct Storages{N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} <: + AbstractAssets{N, L, T, P} names::Vector{String} categories::Vector{String} @@ -94,14 +88,18 @@ struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L, λ::Matrix{Float64} μ::Matrix{Float64} - function Storages{N,L,T,P,E}( - names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, - chargecapacity::Matrix{Int}, dischargecapacity::Matrix{Int}, - energycapacity::Matrix{Int}, chargeefficiency::Matrix{Float64}, - dischargeefficiency::Matrix{Float64}, carryoverefficiency::Matrix{Float64}, - λ::Matrix{Float64}, μ::Matrix{Float64} - ) where {N,L,T,P,E} - + function Storages{N, L, T, P, E}( + names::Vector{<:AbstractString}, + categories::Vector{<:AbstractString}, + chargecapacity::Matrix{Int}, + dischargecapacity::Matrix{Int}, + energycapacity::Matrix{Int}, + chargeefficiency::Matrix{Float64}, + dischargeefficiency::Matrix{Float64}, + carryoverefficiency::Matrix{Float64}, + λ::Matrix{Float64}, + μ::Matrix{Float64}, + ) where {N, L, T, P, E} n_stors = length(names) @assert length(categories) == n_stors @assert allunique(names) @@ -125,13 +123,19 @@ struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L, @assert all(0 .<= λ .<= 1) @assert all(0 .<= μ .<= 1) - new{N,L,T,P,E}(string.(names), string.(categories), - chargecapacity, dischargecapacity, energycapacity, - chargeefficiency, dischargeefficiency, carryoverefficiency, - λ, μ) - + new{N, L, T, P, E}( + string.(names), + string.(categories), + chargecapacity, + dischargecapacity, + energycapacity, + chargeefficiency, + dischargeefficiency, + carryoverefficiency, + λ, + μ, + ) end - end Base.:(==)(x::T, y::T) where {T <: Storages} = @@ -146,14 +150,20 @@ Base.:(==)(x::T, y::T) where {T <: Storages} = x.λ == y.λ && x.μ == y.μ -Base.getindex(s::S, idxs::AbstractVector{Int}) where {S <: Storages} = - S(s.names[idxs], s.categories[idxs],s.charge_capacity[idxs,:], - s.discharge_capacity[idxs, :],s.energy_capacity[idxs, :], - s.charge_efficiency[idxs, :], s.discharge_efficiency[idxs, :], - s.carryover_efficiency[idxs, :],s.λ[idxs, :], s.μ[idxs, :]) - -function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E} - +Base.getindex(s::S, idxs::AbstractVector{Int}) where {S <: Storages} = S( + s.names[idxs], + s.categories[idxs], + s.charge_capacity[idxs, :], + s.discharge_capacity[idxs, :], + s.energy_capacity[idxs, :], + s.charge_efficiency[idxs, :], + s.discharge_efficiency[idxs, :], + s.carryover_efficiency[idxs, :], + s.λ[idxs, :], + s.μ[idxs, :], +) + +function Base.vcat(stors::Storages{N, L, T, P, E}...) where {N, L, T, P, E} n_stors = sum(length(s) for s in stors) names = Vector{String}(undef, n_stors) @@ -161,7 +171,7 @@ function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E} charge_capacity = Matrix{Int}(undef, n_stors, N) discharge_capacity = Matrix{Int}(undef, n_stors, N) - energy_capacity = Matrix{Int}(undef, n_stors, N) + energy_capacity = Matrix{Int}(undef, n_stors, N) charge_efficiency = Matrix{Float64}(undef, n_stors, N) discharge_efficiency = Matrix{Float64}(undef, n_stors, N) @@ -173,7 +183,6 @@ function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E} last_idx = 0 for s in stors - n = length(s) rows = last_idx .+ (1:n) @@ -192,16 +201,24 @@ function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E} μ[rows, :] = s.μ last_idx += n - end - return Storages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency, - carryover_efficiency, λ, μ) - + return Storages{N, L, T, P, E}( + names, + categories, + charge_capacity, + discharge_capacity, + energy_capacity, + charge_efficiency, + discharge_efficiency, + carryover_efficiency, + λ, + μ, + ) end -struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P} - +struct GeneratorStorages{N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} <: + AbstractAssets{N, L, T, P} names::Vector{String} categories::Vector{String} @@ -220,17 +237,21 @@ struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAs λ::Matrix{Float64} μ::Matrix{Float64} - function GeneratorStorages{N,L,T,P,E}( - names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, - charge_capacity::Matrix{Int}, discharge_capacity::Matrix{Int}, + function GeneratorStorages{N, L, T, P, E}( + names::Vector{<:AbstractString}, + categories::Vector{<:AbstractString}, + charge_capacity::Matrix{Int}, + discharge_capacity::Matrix{Int}, energy_capacity::Matrix{Int}, - charge_efficiency::Matrix{Float64}, discharge_efficiency::Matrix{Float64}, + charge_efficiency::Matrix{Float64}, + discharge_efficiency::Matrix{Float64}, carryover_efficiency::Matrix{Float64}, inflow::Matrix{Int}, - gridwithdrawal_capacity::Matrix{Int}, gridinjection_capacity::Matrix{Int}, - λ::Matrix{Float64}, μ::Matrix{Float64} - ) where {N,L,T,P,E} - + gridwithdrawal_capacity::Matrix{Int}, + gridinjection_capacity::Matrix{Int}, + λ::Matrix{Float64}, + μ::Matrix{Float64}, + ) where {N, L, T, P, E} n_stors = length(names) @assert length(categories) == n_stors @assert allunique(names) @@ -264,15 +285,22 @@ struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAs @assert all(0 .<= λ .<= 1) @assert all(0 .<= μ .<= 1) - new{N,L,T,P,E}( - string.(names), string.(categories), - charge_capacity, discharge_capacity, energy_capacity, - charge_efficiency, discharge_efficiency, carryover_efficiency, - inflow, gridwithdrawal_capacity, gridinjection_capacity, - λ, μ) - + new{N, L, T, P, E}( + string.(names), + string.(categories), + charge_capacity, + discharge_capacity, + energy_capacity, + charge_efficiency, + discharge_efficiency, + carryover_efficiency, + inflow, + gridwithdrawal_capacity, + gridinjection_capacity, + λ, + μ, + ) end - end Base.:(==)(x::T, y::T) where {T <: GeneratorStorages} = @@ -290,16 +318,23 @@ Base.:(==)(x::T, y::T) where {T <: GeneratorStorages} = x.λ == y.λ && x.μ == y.μ -Base.getindex(g_s::G, idxs::AbstractVector{Int}) where {G <: GeneratorStorages} = - G(g_s.names[idxs], g_s.categories[idxs], g_s.charge_capacity[idxs,:], - g_s.discharge_capacity[idxs, :], g_s.energy_capacity[idxs, :], - g_s.charge_efficiency[idxs, :], g_s.discharge_efficiency[idxs, :], - g_s.carryover_efficiency[idxs, :],g_s.inflow[idxs, :], - g_s.gridwithdrawal_capacity[idxs, :],g_s.gridinjection_capacity[idxs, :], - g_s.λ[idxs, :], g_s.μ[idxs, :]) - -function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P, E} - +Base.getindex(g_s::G, idxs::AbstractVector{Int}) where {G <: GeneratorStorages} = G( + g_s.names[idxs], + g_s.categories[idxs], + g_s.charge_capacity[idxs, :], + g_s.discharge_capacity[idxs, :], + g_s.energy_capacity[idxs, :], + g_s.charge_efficiency[idxs, :], + g_s.discharge_efficiency[idxs, :], + g_s.carryover_efficiency[idxs, :], + g_s.inflow[idxs, :], + g_s.gridwithdrawal_capacity[idxs, :], + g_s.gridinjection_capacity[idxs, :], + g_s.λ[idxs, :], + g_s.μ[idxs, :], +) + +function Base.vcat(gen_stors::GeneratorStorages{N, L, T, P, E}...) where {N, L, T, P, E} n_gen_stors = sum(length(g_s) for g_s in gen_stors) names = Vector{String}(undef, n_gen_stors) @@ -307,7 +342,7 @@ function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P charge_capacity = Matrix{Int}(undef, n_gen_stors, N) discharge_capacity = Matrix{Int}(undef, n_gen_stors, N) - energy_capacity = Matrix{Int}(undef, n_gen_stors, N) + energy_capacity = Matrix{Int}(undef, n_gen_stors, N) charge_efficiency = Matrix{Float64}(undef, n_gen_stors, N) discharge_efficiency = Matrix{Float64}(undef, n_gen_stors, N) @@ -323,7 +358,6 @@ function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P last_idx = 0 for g_s in gen_stors - n = length(g_s) rows = last_idx .+ (1:n) @@ -346,16 +380,26 @@ function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P μ[rows, :] = g_s.μ last_idx += n - end - return GeneratorStorages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency, - carryover_efficiency,inflow, gridwithdrawal_capacity, gridinjection_capacity, λ, μ) - + return GeneratorStorages{N, L, T, P, E}( + names, + categories, + charge_capacity, + discharge_capacity, + energy_capacity, + charge_efficiency, + discharge_efficiency, + carryover_efficiency, + inflow, + gridwithdrawal_capacity, + gridinjection_capacity, + λ, + μ, + ) end -struct Lines{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} - +struct Lines{N, L, T <: Period, P <: PowerUnit} <: AbstractAssets{N, L, T, P} names::Vector{String} categories::Vector{String} @@ -365,12 +409,14 @@ struct Lines{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} λ::Matrix{Float64} μ::Matrix{Float64} - function Lines{N,L,T,P}( - names::Vector{<:AbstractString}, categories::Vector{<:AbstractString}, - forward_capacity::Matrix{Int}, backward_capacity::Matrix{Int}, - λ::Matrix{Float64}, μ::Matrix{Float64} - ) where {N,L,T,P} - + function Lines{N, L, T, P}( + names::Vector{<:AbstractString}, + categories::Vector{<:AbstractString}, + forward_capacity::Matrix{Int}, + backward_capacity::Matrix{Int}, + λ::Matrix{Float64}, + μ::Matrix{Float64}, + ) where {N, L, T, P} n_lines = length(names) @assert length(categories) == n_lines @assert allunique(names) @@ -385,10 +431,15 @@ struct Lines{N,L,T<:Period,P<:PowerUnit} <: AbstractAssets{N,L,T,P} @assert all(0 .<= λ .<= 1) @assert all(0 .<= μ .<= 1) - new{N,L,T,P}(string.(names), string.(categories), forward_capacity, backward_capacity, λ, μ) - + new{N, L, T, P}( + string.(names), + string.(categories), + forward_capacity, + backward_capacity, + λ, + μ, + ) end - end Base.:(==)(x::T, y::T) where {T <: Lines} = @@ -399,12 +450,16 @@ Base.:(==)(x::T, y::T) where {T <: Lines} = x.λ == y.λ && x.μ == y.μ -Base.getindex(lines::L, idxs::AbstractVector{Int}) where {L <: Lines} = - L(lines.names[idxs], lines.categories[idxs],lines.forward_capacity[idxs,:], - lines.backward_capacity[idxs, :],lines.λ[idxs, :], lines.μ[idxs, :]) - -function Base.vcat(lines::Lines{N,L,T,P}...) where {N, L, T, P} +Base.getindex(lines::L, idxs::AbstractVector{Int}) where {L <: Lines} = L( + lines.names[idxs], + lines.categories[idxs], + lines.forward_capacity[idxs, :], + lines.backward_capacity[idxs, :], + lines.λ[idxs, :], + lines.μ[idxs, :], +) +function Base.vcat(lines::Lines{N, L, T, P}...) where {N, L, T, P} n_lines = sum(length(line) for line in lines) names = Vector{String}(undef, n_lines) @@ -412,14 +467,13 @@ function Base.vcat(lines::Lines{N,L,T,P}...) where {N, L, T, P} forward_capacity = Matrix{Int}(undef, n_lines, N) backward_capacity = Matrix{Int}(undef, n_lines, N) - - λ = Matrix{Float64}(undef,n_lines, N) - μ = Matrix{Float64}(undef,n_lines, N) + + λ = Matrix{Float64}(undef, n_lines, N) + μ = Matrix{Float64}(undef, n_lines, N) last_idx = 0 for line in lines - n = length(line) rows = last_idx .+ (1:n) @@ -433,9 +487,7 @@ function Base.vcat(lines::Lines{N,L,T,P}...) where {N, L, T, P} μ[rows, :] = line.μ last_idx += n - end - return Lines{N,L,T,P}(names, categories, forward_capacity, backward_capacity, λ, μ) - -end \ No newline at end of file + return Lines{N, L, T, P}(names, categories, forward_capacity, backward_capacity, λ, μ) +end diff --git a/src/PRAS/PRASBase/collections.jl b/src/PRAS/PRASBase/collections.jl index e1b003a..6549b06 100644 --- a/src/PRAS/PRASBase/collections.jl +++ b/src/PRAS/PRASBase/collections.jl @@ -1,41 +1,36 @@ -struct Regions{N,P<:PowerUnit} - +struct Regions{N, P <: PowerUnit} names::Vector{String} load::Matrix{Int} - function Regions{N,P}( - names::Vector{<:AbstractString}, load::Matrix{Int} - ) where {N,P<:PowerUnit} - + function Regions{N, P}( + names::Vector{<:AbstractString}, + load::Matrix{Int}, + ) where {N, P <: PowerUnit} n_regions = length(names) @assert size(load) == (n_regions, N) @assert all(load .>= 0) - new{N,P}(string.(names), load) - + new{N, P}(string.(names), load) end - end -Base.:(==)(x::T, y::T) where {T <: Regions} = - x.names == y.names && - x.load == y.load +Base.:(==)(x::T, y::T) where {T <: Regions} = x.names == y.names && x.load == y.load Base.length(r::Regions) = length(r.names) -struct Interfaces{N,P<:PowerUnit} - +struct Interfaces{N, P <: PowerUnit} regions_from::Vector{Int} regions_to::Vector{Int} limit_forward::Matrix{Int} limit_backward::Matrix{Int} - function Interfaces{N,P}( - regions_from::Vector{Int}, regions_to::Vector{Int}, - forwardcapacity::Matrix{Int}, backwardcapacity::Matrix{Int} - ) where {N,P<:PowerUnit} - + function Interfaces{N, P}( + regions_from::Vector{Int}, + regions_to::Vector{Int}, + forwardcapacity::Matrix{Int}, + backwardcapacity::Matrix{Int}, + ) where {N, P <: PowerUnit} n_interfaces = length(regions_from) @assert length(regions_to) == n_interfaces @@ -44,10 +39,8 @@ struct Interfaces{N,P<:PowerUnit} @assert all(forwardcapacity .>= 0) @assert all(backwardcapacity .>= 0) - new{N,P}(regions_from, regions_to, forwardcapacity, backwardcapacity) - + new{N, P}(regions_from, regions_to, forwardcapacity, backwardcapacity) end - end Base.:(==)(x::T, y::T) where {T <: Interfaces} = diff --git a/src/PRAS/PRASBase/read.jl b/src/PRAS/PRASBase/read.jl index a600c38..8501987 100644 --- a/src/PRAS/PRASBase/read.jl +++ b/src/PRAS/PRASBase/read.jl @@ -1,35 +1,28 @@ """ - SystemModel(filename::String) Load a `SystemModel` from an appropriately-formatted HDF5 file on disk. """ function SystemModel(inputfile::String) - system = h5open(inputfile, "r") do f::File - version, versionstring = readversion(f) # Determine the appropriate version of the importer to use - return if (0,5,0) <= version < (0,7,0) + return if (0, 5, 0) <= version < (0, 7, 0) systemmodel_0_5(f) else error("PRAS file format $versionstring not supported by this version of PRASBase.") end - end return system - end - function systemmodel_0_5(f::File) - metadata = attributes(f) - start_timestamp = ZonedDateTime(read(metadata["start_timestamp"]), - dateformat"yyyy-mm-ddTHH:MM:SSz") + start_timestamp = + ZonedDateTime(read(metadata["start_timestamp"]), dateformat"yyyy-mm-ddTHH:MM:SSz") N = Int(read(metadata["timestep_count"])) L = Int(read(metadata["timestep_length"])) @@ -38,7 +31,7 @@ function systemmodel_0_5(f::File) E = energyunits[read(metadata["energy_unit"])] timestep = T(L) - end_timestamp = start_timestamp + (N-1)*timestep + end_timestamp = start_timestamp + (N - 1) * timestep timestamps = StepRange(start_timestamp, timestep, end_timestamp) has_regions = haskey(f, "regions") @@ -48,62 +41,61 @@ function systemmodel_0_5(f::File) has_interfaces = haskey(f, "interfaces") has_lines = haskey(f, "lines") - has_regions || - error("Region data must be provided") + has_regions || error("Region data must be provided") - has_generators || has_generatorstorages || + has_generators || + has_generatorstorages || error("Generator or generator storage data (or both) must be provided") xor(has_interfaces, has_lines) && error("Both (or neither) interface and line data must be provided") regionnames = readvector(f["regions/_core"], :name) - regions = Regions{N,P}( - regionnames, - Int.(read(f["regions/load"])) - ) - regionlookup = Dict(n=>i for (i, n) in enumerate(regionnames)) + regions = Regions{N, P}(regionnames, Int.(read(f["regions/load"]))) + regionlookup = Dict(n => i for (i, n) in enumerate(regionnames)) n_regions = length(regions) if has_generators - gen_core = read(f["generators/_core"]) - gen_names, gen_categories, gen_regionnames = readvector.( - Ref(gen_core), [:name, :category, :region]) + gen_names, gen_categories, gen_regionnames = + readvector.(Ref(gen_core), [:name, :category, :region]) gen_regions = getindex.(Ref(regionlookup), gen_regionnames) region_order = sortperm(gen_regions) - generators = Generators{N,L,T,P}( - gen_names[region_order], gen_categories[region_order], + generators = Generators{N, L, T, P}( + gen_names[region_order], + gen_categories[region_order], Int.(read(f["generators/capacity"]))[region_order, :], read(f["generators/failureprobability"])[region_order, :], - read(f["generators/repairprobability"])[region_order, :] + read(f["generators/repairprobability"])[region_order, :], ) region_gen_idxs = makeidxlist(gen_regions[region_order], n_regions) else - - generators = Generators{N,L,T,P}( - String[], String[], zeros(Int, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N)) + generators = Generators{N, L, T, P}( + String[], + String[], + zeros(Int, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + ) region_gen_idxs = fill(1:0, n_regions) - end if has_storages - stor_core = read(f["storages/_core"]) - stor_names, stor_categories, stor_regionnames = readvector.( - Ref(stor_core), [:name, :category, :region]) + stor_names, stor_categories, stor_regionnames = + readvector.(Ref(stor_core), [:name, :category, :region]) stor_regions = getindex.(Ref(regionlookup), stor_regionnames) region_order = sortperm(stor_regions) - storages = Storages{N,L,T,P,E}( - stor_names[region_order], stor_categories[region_order], + storages = Storages{N, L, T, P, E}( + stor_names[region_order], + stor_categories[region_order], Int.(read(f["storages/chargecapacity"]))[region_order, :], Int.(read(f["storages/dischargecapacity"]))[region_order, :], Int.(read(f["storages/energycapacity"]))[region_order, :], @@ -111,35 +103,39 @@ function systemmodel_0_5(f::File) read(f["storages/dischargeefficiency"])[region_order, :], read(f["storages/carryoverefficiency"])[region_order, :], read(f["storages/failureprobability"])[region_order, :], - read(f["storages/repairprobability"])[region_order, :] + read(f["storages/repairprobability"])[region_order, :], ) region_stor_idxs = makeidxlist(stor_regions[region_order], n_regions) else - - storages = Storages{N,L,T,P,E}( - String[], String[], - zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N)) + storages = Storages{N, L, T, P, E}( + String[], + String[], + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + ) region_stor_idxs = fill(1:0, n_regions) - end - if has_generatorstorages - genstor_core = read(f["generatorstorages/_core"]) - genstor_names, genstor_categories, genstor_regionnames = readvector.( - Ref(genstor_core), [:name, :category, :region]) + genstor_names, genstor_categories, genstor_regionnames = + readvector.(Ref(genstor_core), [:name, :category, :region]) genstor_regions = getindex.(Ref(regionlookup), genstor_regionnames) region_order = sortperm(genstor_regions) - generatorstorages = GeneratorStorages{N,L,T,P,E}( - genstor_names[region_order], genstor_categories[region_order], + generatorstorages = GeneratorStorages{N, L, T, P, E}( + genstor_names[region_order], + genstor_categories[region_order], Int.(read(f["generatorstorages/chargecapacity"]))[region_order, :], Int.(read(f["generatorstorages/dischargecapacity"]))[region_order, :], Int.(read(f["generatorstorages/energycapacity"]))[region_order, :], @@ -150,25 +146,32 @@ function systemmodel_0_5(f::File) Int.(read(f["generatorstorages/gridwithdrawalcapacity"]))[region_order, :], Int.(read(f["generatorstorages/gridinjectioncapacity"]))[region_order, :], read(f["generatorstorages/failureprobability"])[region_order, :], - read(f["generatorstorages/repairprobability"])[region_order, :]) + read(f["generatorstorages/repairprobability"])[region_order, :], + ) region_genstor_idxs = makeidxlist(genstor_regions[region_order], n_regions) else - - generatorstorages = GeneratorStorages{N,L,T,P,E}( - String[], String[], - zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N), - zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N)) + generatorstorages = GeneratorStorages{N, L, T, P, E}( + String[], + String[], + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + ) region_genstor_idxs = fill(1:0, n_regions) - end if has_interfaces - interfaces_core = read(f["interfaces/_core"]) from_regionnames, to_regionnames = readvector.(Ref(interfaces_core), [:region_from, :region_to]) @@ -190,16 +193,19 @@ function systemmodel_0_5(f::File) backwardcapacity[i, :] .= forwardcapacity[i, :] forwardcapacity[i, :] .= new_forwardcapacity elseif from_region == to_region - error("Cannot have an interface to and from " * - "the same region ($(from_region))") + error( + "Cannot have an interface to and from " * + "the same region ($(from_region))", + ) end end - interfaces = Interfaces{N,P}( - from_regions, to_regions, forwardcapacity, backwardcapacity) + interfaces = + Interfaces{N, P}(from_regions, to_regions, forwardcapacity, backwardcapacity) - interface_lookup = Dict((r1, r2) => i for (i, (r1, r2)) - in enumerate(tuple.(from_regions, to_regions))) + interface_lookup = Dict( + (r1, r2) => i for (i, (r1, r2)) in enumerate(tuple.(from_regions, to_regions)) + ) lines_core = read(f["lines/_core"]) line_names, line_categories, line_fromregionnames, line_toregionnames = @@ -209,7 +215,7 @@ function systemmodel_0_5(f::File) n_lines = length(line_names) line_fromregions = getindex.(Ref(regionlookup), line_fromregionnames) - line_toregions = getindex.(Ref(regionlookup), line_toregionnames) + line_toregions = getindex.(Ref(regionlookup), line_toregionnames) # Force line definitions as smaller => larger region numbers for i in 1:n_lines @@ -222,45 +228,56 @@ function systemmodel_0_5(f::File) line_backwardcapacity[i, :] .= line_forwardcapacity[i, :] line_forwardcapacity[i, :] = new_forwardcapacity elseif from_region == to_region - error("Cannot have a line ($(line_names[i])) to and from " * - "the same region ($(from_region))") + error( + "Cannot have a line ($(line_names[i])) to and from " * + "the same region ($(from_region))", + ) end end - line_interfaces = getindex.(Ref(interface_lookup), - tuple.(line_fromregions, line_toregions)) + line_interfaces = + getindex.(Ref(interface_lookup), tuple.(line_fromregions, line_toregions)) interface_order = sortperm(line_interfaces) - lines = Lines{N,L,T,P}( - line_names[interface_order], line_categories[interface_order], + lines = Lines{N, L, T, P}( + line_names[interface_order], + line_categories[interface_order], line_forwardcapacity[interface_order, :], line_backwardcapacity[interface_order, :], read(f["lines/failureprobability"])[interface_order, :], - read(f["lines/repairprobability"])[interface_order, :]) + read(f["lines/repairprobability"])[interface_order, :], + ) interface_line_idxs = makeidxlist(line_interfaces[interface_order], n_interfaces) else - - interfaces = Interfaces{N,P}( - Int[], Int[], zeros(Int, 0, N), zeros(Int, 0, N)) - - lines = Lines{N,L,T,P}( - String[], String[], zeros(Int, 0, N), zeros(Int, 0, N), - zeros(Float64, 0, N), zeros(Float64, 0, N)) + interfaces = Interfaces{N, P}(Int[], Int[], zeros(Int, 0, N), zeros(Int, 0, N)) + + lines = Lines{N, L, T, P}( + String[], + String[], + zeros(Int, 0, N), + zeros(Int, 0, N), + zeros(Float64, 0, N), + zeros(Float64, 0, N), + ) interface_line_idxs = UnitRange{Int}[] - end return SystemModel( - regions, interfaces, - generators, region_gen_idxs, - storages, region_stor_idxs, - generatorstorages, region_genstor_idxs, - lines, interface_line_idxs, - timestamps) - + regions, + interfaces, + generators, + region_gen_idxs, + storages, + region_stor_idxs, + generatorstorages, + region_genstor_idxs, + lines, + interface_line_idxs, + timestamps, + ) end """ @@ -268,10 +285,10 @@ Attempts to parse the file's "vX.Y.Z" version label into (x::Int, y::Int, z::Int Errors if the label cannot be found or parsed as expected. """ function readversion(f::File) - haskey(attributes(f), "pras_dataversion") || error( - "File format version indicator could not be found - the file may " * - "not be a PRAS SystemModel representation.") + "File format version indicator could not be found - the file may " * + "not be a PRAS SystemModel representation.", + ) versionstring = read(attributes(f)["pras_dataversion"]) @@ -281,12 +298,11 @@ function readversion(f::File) major, minor, patch = parse.(Int, version.captures) return (major, minor, patch), versionstring - end """ Attempts to extract a vector of elements from an HDF5 compound datatype, corresponding to `field`. """ -readvector(d::Dataset, field::Union{Symbol,Int}) = readvector(read(d), field) -readvector(d::Vector{<:NamedTuple}, field::Union{Symbol,Int}) = getindex.(d, field) +readvector(d::Dataset, field::Union{Symbol, Int}) = readvector(read(d), field) +readvector(d::Vector{<:NamedTuple}, field::Union{Symbol, Int}) = getindex.(d, field) diff --git a/src/PRAS/PRASBase/units.jl b/src/PRAS/PRASBase/units.jl index 1b7bd8f..08c517a 100644 --- a/src/PRAS/PRASBase/units.jl +++ b/src/PRAS/PRASBase/units.jl @@ -17,9 +17,7 @@ conversionfactor(::Type{Hour}, ::Type{Hour}) = 1 conversionfactor(::Type{Hour}, ::Type{Day}) = 1 / 24 conversionfactor(::Type{Day}, ::Type{Hour}) = 24 -timeunits = Dict( - unitsymbol(T) => T - for T in [Minute, Hour, Day, Year]) +timeunits = Dict(unitsymbol(T) => T for T in [Minute, Hour, Day, Year]) # Define power units @@ -49,9 +47,7 @@ conversionfactor(::Type{GW}, ::Type{MW}) = 1000 conversionfactor(::Type{MW}, ::Type{TW}) = 1 / 1_000_000 conversionfactor(::Type{TW}, ::Type{MW}) = 1_000_000 -powerunits = Dict( - unitsymbol(T) => T - for T in [kW, MW, GW, TW]) +powerunits = Dict(unitsymbol(T) => T for T in [kW, MW, GW, TW]) # Define energy units @@ -72,12 +68,9 @@ subunits(::Type{MWh}) = (MW, Hour) subunits(::Type{GWh}) = (GW, Hour) subunits(::Type{TWh}) = (TW, Hour) -energyunits = Dict( - unitsymbol(T) => T - for T in [kWh, MWh, GWh, TWh]) +energyunits = Dict(unitsymbol(T) => T for T in [kWh, MWh, GWh, TWh]) function conversionfactor(F::Type{<:EnergyUnit}, T::Type{<:EnergyUnit}) - from_power, from_time = subunits(F) to_power, to_time = subunits(T) @@ -85,11 +78,14 @@ function conversionfactor(F::Type{<:EnergyUnit}, T::Type{<:EnergyUnit}) timeconversion = conversionfactor(from_time, to_time) return powerconversion * timeconversion - end function conversionfactor( - L::Int, T::Type{<:Period}, P::Type{<:PowerUnit}, E::Type{<:EnergyUnit}) + L::Int, + T::Type{<:Period}, + P::Type{<:PowerUnit}, + E::Type{<:EnergyUnit}, +) to_power, to_time = subunits(E) powerconversion = conversionfactor(P, to_power) timeconversion = conversionfactor(T, to_time) @@ -97,7 +93,11 @@ function conversionfactor( end function conversionfactor( - L::Int, T::Type{<:Period}, E::Type{<:EnergyUnit}, P::Type{<:PowerUnit}) + L::Int, + T::Type{<:Period}, + E::Type{<:EnergyUnit}, + P::Type{<:PowerUnit}, +) from_power, from_time = subunits(E) powerconversion = conversionfactor(from_power, P) timeconversion = conversionfactor(from_time, T) @@ -105,12 +105,17 @@ function conversionfactor( end powertoenergy( - p::Real, P::Type{<:PowerUnit}, - L::Real, T::Type{<:Period}, - E::Type{<:EnergyUnit}) = p*conversionfactor(L, T, P, E) + p::Real, + P::Type{<:PowerUnit}, + L::Real, + T::Type{<:Period}, + E::Type{<:EnergyUnit}, +) = p * conversionfactor(L, T, P, E) energytopower( - e::Real, E::Type{<:EnergyUnit}, - L::Real, T::Type{<:Period}, - P::Type{<:PowerUnit}) = e*conversionfactor(L, T, E, P) - + e::Real, + E::Type{<:EnergyUnit}, + L::Real, + T::Type{<:Period}, + P::Type{<:PowerUnit}, +) = e * conversionfactor(L, T, E, P) diff --git a/src/PRAS/PRASBase/utils.jl b/src/PRAS/PRASBase/utils.jl index a4f324b..c61079e 100644 --- a/src/PRAS/PRASBase/utils.jl +++ b/src/PRAS/PRASBase/utils.jl @@ -1,5 +1,4 @@ function makeidxlist(collectionidxs::Vector{Int}, n_collections::Int) - n_assets = length(collectionidxs) idxlist = Vector{UnitRange{Int}}(undef, n_collections) @@ -8,23 +7,22 @@ function makeidxlist(collectionidxs::Vector{Int}, n_collections::Int) a = 1 while a <= n_assets - if collectionidxs[a] > active_collection - idxlist[active_collection] = start_idx:(a-1) + if collectionidxs[a] > active_collection + idxlist[active_collection] = start_idx:(a - 1) active_collection += 1 start_idx = a - else - a += 1 - end + else + a += 1 + end end - idxlist[active_collection] = start_idx:n_assets + idxlist[active_collection] = start_idx:n_assets active_collection += 1 while active_collection <= n_collections - idxlist[active_collection] = (n_assets+1):n_assets + idxlist[active_collection] = (n_assets + 1):n_assets active_collection += 1 end return idxlist - end diff --git a/src/PRAS/PRASBase/write.jl b/src/PRAS/PRASBase/write.jl index c1ec757..08e3115 100644 --- a/src/PRAS/PRASBase/write.jl +++ b/src/PRAS/PRASBase/write.jl @@ -4,14 +4,15 @@ savemodel(sys::SystemModel, outfile::String) -> nothing Export a PRAS SystemModel `sys` as a .pras file, saved to `outfile` """ function savemodel( - sys::SystemModel, outfile::String; - string_length::Int=64, compression_level::Int=1, verbose::Bool=false) - - verbose && - @info "The PRAS system being exported is of type $(typeof(sys))" + sys::SystemModel, + outfile::String; + string_length::Int=64, + compression_level::Int=1, + verbose::Bool=false, +) + verbose && @info "The PRAS system being exported is of type $(typeof(sys))" h5open(outfile, "w") do f::File - verbose && @info "Processing metadata for .pras file ..." process_metadata!(f, sys) @@ -43,37 +44,30 @@ function savemodel( verbose && @info "Processing Lines and Interfaces for .pras file ..." process_lines_interfaces!(f, sys, string_length, compression_level) end - end - verbose && @info "Successfully exported the PRAS SystemModel to " * - ".pras file " * outfile + verbose && + @info "Successfully exported the PRAS SystemModel to " * ".pras file " * outfile return - end -function process_metadata!( - f::File, sys::SystemModel{N,L,T,P,E}) where {N,L,T,P,E} - +function process_metadata!(f::File, sys::SystemModel{N, L, T, P, E}) where {N, L, T, P, E} attrs = attributes(f) - + attrs["timestep_count"] = N attrs["timestep_length"] = L attrs["timestep_unit"] = unitsymbol(T) attrs["power_unit"] = unitsymbol(P) attrs["energy_unit"] = unitsymbol(E) - attrs["start_timestamp"] = string(sys.timestamps.start); + attrs["start_timestamp"] = string(sys.timestamps.start) attrs["pras_dataversion"] = PRAS_VERSION return - end -function process_regions!( - f::File, sys::SystemModel, strlen::Int, compression::Int) - +function process_regions!(f::File, sys::SystemModel, strlen::Int, compression::Int) n_regions = length(sys.regions.names) regions = create_group(f, "regions") @@ -82,15 +76,12 @@ function process_regions!( string_table!(regions, "_core", regions_core_colnames, regions_core, strlen) - regions["load", deflate = compression] = sys.regions.load + regions["load", deflate=compression] = sys.regions.load return - end -function process_generators!( - f::File, sys::SystemModel, strlen::Int, compression::Int) - +function process_generators!(f::File, sys::SystemModel, strlen::Int, compression::Int) generators = create_group(f, "generators") gens_core = Matrix{String}(undef, length(sys.generators), 3) @@ -98,24 +89,21 @@ function process_generators!( gens_core[:, 1] = sys.generators.names gens_core[:, 2] = sys.generators.categories - gens_core[:, 3] = regionnames( - length(sys.generators), sys.regions.names, sys.region_gen_idxs) + gens_core[:, 3] = + regionnames(length(sys.generators), sys.regions.names, sys.region_gen_idxs) string_table!(generators, "_core", gens_core_colnames, gens_core, strlen) - generators["capacity", deflate = compression] = sys.generators.capacity + generators["capacity", deflate=compression] = sys.generators.capacity - generators["failureprobability", deflate = compression] = sys.generators.λ + generators["failureprobability", deflate=compression] = sys.generators.λ - generators["repairprobability", deflate = compression] = sys.generators.μ + generators["repairprobability", deflate=compression] = sys.generators.μ return - end -function process_storages!( - f::File, sys::SystemModel, strlen::Int, compression::Int) - +function process_storages!(f::File, sys::SystemModel, strlen::Int, compression::Int) storages = create_group(f, "storages") stors_core = Matrix{String}(undef, length(sys.storages), 3) @@ -123,40 +111,36 @@ function process_storages!( stors_core[:, 1] = sys.storages.names stors_core[:, 2] = sys.storages.categories - stors_core[:, 3] = regionnames( - length(sys.storages), sys.regions.names, sys.region_stor_idxs) + stors_core[:, 3] = + regionnames(length(sys.storages), sys.regions.names, sys.region_stor_idxs) string_table!(storages, "_core", stors_core_colnames, stors_core, strlen) - storages["chargecapacity", deflate = compression] = - sys.storages.charge_capacity + storages["chargecapacity", deflate=compression] = sys.storages.charge_capacity - storages["dischargecapacity", deflate = compression] = - sys.storages.discharge_capacity + storages["dischargecapacity", deflate=compression] = sys.storages.discharge_capacity - storages["energycapacity", deflate = compression] = - sys.storages.energy_capacity + storages["energycapacity", deflate=compression] = sys.storages.energy_capacity - storages["chargeefficiency", deflate = compression] = - sys.storages.charge_efficiency + storages["chargeefficiency", deflate=compression] = sys.storages.charge_efficiency - storages["dischargeefficiency", deflate = compression] = - sys.storages.discharge_efficiency + storages["dischargeefficiency", deflate=compression] = sys.storages.discharge_efficiency - storages["carryoverefficiency", deflate = compression] = - sys.storages.carryover_efficiency + storages["carryoverefficiency", deflate=compression] = sys.storages.carryover_efficiency - storages["failureprobability", deflate = compression] = sys.storages.λ + storages["failureprobability", deflate=compression] = sys.storages.λ - storages["repairprobability", deflate = compression] = sys.storages.μ + storages["repairprobability", deflate=compression] = sys.storages.μ return - end function process_generatorstorages!( - f::File, sys::SystemModel, strlen::Int, compression::Int) - + f::File, + sys::SystemModel, + strlen::Int, + compression::Int, +) generatorstorages = create_group(f, "generatorstorages") genstors_core = Matrix{String}(undef, length(sys.generatorstorages), 3) @@ -165,51 +149,47 @@ function process_generatorstorages!( genstors_core[:, 1] = sys.generatorstorages.names genstors_core[:, 2] = sys.generatorstorages.categories genstors_core[:, 3] = regionnames( - length(sys.generatorstorages), sys.regions.names, sys.region_genstor_idxs) + length(sys.generatorstorages), + sys.regions.names, + sys.region_genstor_idxs, + ) - string_table!(generatorstorages, "_core", - genstors_core_colnames, genstors_core, strlen) + string_table!(generatorstorages, "_core", genstors_core_colnames, genstors_core, strlen) - generatorstorages["inflow", deflate = compression] = - sys.generatorstorages.inflow + generatorstorages["inflow", deflate=compression] = sys.generatorstorages.inflow - generatorstorages["gridwithdrawalcapacity", deflate = compression] = + generatorstorages["gridwithdrawalcapacity", deflate=compression] = sys.generatorstorages.gridwithdrawal_capacity - generatorstorages["gridinjectioncapacity", deflate = compression] = + generatorstorages["gridinjectioncapacity", deflate=compression] = sys.generatorstorages.gridinjection_capacity - generatorstorages["chargecapacity", deflate = compression] = + generatorstorages["chargecapacity", deflate=compression] = sys.generatorstorages.charge_capacity - generatorstorages["dischargecapacity", deflate = compression] = + generatorstorages["dischargecapacity", deflate=compression] = sys.generatorstorages.discharge_capacity - generatorstorages["energycapacity", deflate = compression] = + generatorstorages["energycapacity", deflate=compression] = sys.generatorstorages.energy_capacity - generatorstorages["chargeefficiency", deflate = compression] = + generatorstorages["chargeefficiency", deflate=compression] = sys.generatorstorages.charge_efficiency - generatorstorages["dischargeefficiency", deflate = compression] = + generatorstorages["dischargeefficiency", deflate=compression] = sys.generatorstorages.discharge_efficiency - generatorstorages["carryoverefficiency", deflate = compression] = + generatorstorages["carryoverefficiency", deflate=compression] = sys.generatorstorages.carryover_efficiency - generatorstorages["failureprobability", deflate = compression] = - sys.generatorstorages.λ + generatorstorages["failureprobability", deflate=compression] = sys.generatorstorages.λ - generatorstorages["repairprobability", deflate = compression] = - sys.generatorstorages.μ + generatorstorages["repairprobability", deflate=compression] = sys.generatorstorages.μ return - end -function process_lines_interfaces!( - f::File, sys::SystemModel, strlen::Int, compression::Int) - +function process_lines_interfaces!(f::File, sys::SystemModel, strlen::Int, compression::Int) lines = create_group(f, "lines") lines_core = Matrix{String}(undef, length(sys.lines), 4) @@ -217,71 +197,64 @@ function process_lines_interfaces!( lines_core[:, 1] = sys.lines.names lines_core[:, 2] = sys.lines.categories - for (lines, r_from, r_to) in zip(sys.interface_line_idxs, - sys.interfaces.regions_from, - sys.interfaces.regions_to) + for (lines, r_from, r_to) in + zip(sys.interface_line_idxs, sys.interfaces.regions_from, sys.interfaces.regions_to) lines_core[lines, 3] .= sys.regions.names[r_from] lines_core[lines, 4] .= sys.regions.names[r_to] end string_table!(lines, "_core", lines_core_colnames, lines_core, strlen) - lines["forwardcapacity", deflate = compression] = - sys.lines.forward_capacity + lines["forwardcapacity", deflate=compression] = sys.lines.forward_capacity - lines["backwardcapacity", deflate = compression] = - sys.lines.backward_capacity + lines["backwardcapacity", deflate=compression] = sys.lines.backward_capacity - lines["failureprobability", deflate = compression] = sys.lines.λ - - lines["repairprobability", deflate = compression] = sys.lines.μ + lines["failureprobability", deflate=compression] = sys.lines.λ + lines["repairprobability", deflate=compression] = sys.lines.μ interfaces = create_group(f, "interfaces") ints_core = Matrix{String}(undef, length(sys.interfaces), 2) ints_core_colnames = ["region_from", "region_to"] - ints_core[:, 1] = - getindex.(Ref(sys.regions.names), sys.interfaces.regions_from) - ints_core[:, 2] = - getindex.(Ref(sys.regions.names), sys.interfaces.regions_to) + ints_core[:, 1] = getindex.(Ref(sys.regions.names), sys.interfaces.regions_from) + ints_core[:, 2] = getindex.(Ref(sys.regions.names), sys.interfaces.regions_to) string_table!(interfaces, "_core", ints_core_colnames, ints_core, strlen) - interfaces["forwardcapacity", deflate = compression] = - sys.interfaces.limit_forward + interfaces["forwardcapacity", deflate=compression] = sys.interfaces.limit_forward - interfaces["backwardcapacity", deflate = compression] = - sys.interfaces.limit_backward + interfaces["backwardcapacity", deflate=compression] = sys.interfaces.limit_backward return - end function regionnames( - n_units::Int, regions::Vector{String}, unit_idxs::Vector{UnitRange{Int}}) - + n_units::Int, + regions::Vector{String}, + unit_idxs::Vector{UnitRange{Int}}, +) result = Vector{String}(undef, n_units) for (r, units) in enumerate(unit_idxs) result[units] .= regions[r] end return result - end function string_table!( - f::Group, tablename::String, colnames::Vector{String}, - data::Matrix{String}, strlen::Int + f::Group, + tablename::String, + colnames::Vector{String}, + data::Matrix{String}, + strlen::Int, ) - nrows, ncols = size(data) length(colnames) == ncols || error("Number of column names does not match provided data") - allunique(colnames) || - error("All column names must be unique") + allunique(colnames) || error("All column names must be unique") all(x -> x <= strlen, length.(data)) || error("Input data exceeds the specified HDF5 string length") @@ -292,20 +265,16 @@ function string_table!( dt_id = h5t_create(H5T_COMPOUND, ncols * strlen) for (i, colname) in enumerate(colnames) - h5t_insert(dt_id, colname, (i-1)*strlen, stringtype) + h5t_insert(dt_id, colname, (i - 1) * strlen, stringtype) end rawdata = UInt8.(vcat(vec(convertstring.(permutedims(data), strlen))...)) - dset = create_dataset(f, tablename, Datatype(dt_id), - dataspace((nrows,))) - h5d_write( - dset, dt_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, rawdata) - + dset = create_dataset(f, tablename, Datatype(dt_id), dataspace((nrows,))) + h5d_write(dset, dt_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, rawdata) end function convertstring(s::AbstractString, strlen::Int) - oldstring = ascii(s) newstring = fill('\0', strlen) @@ -314,5 +283,4 @@ function convertstring(s::AbstractString, strlen::Int) end return newstring - end diff --git a/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl b/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl index 05a7873..3e0504c 100644 --- a/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl +++ b/src/PRAS/ResourceAdequacy/ResourceAdequacy.jl @@ -17,31 +17,45 @@ import StatsBase: mean, std, stderror import TimeZones: ZonedDateTime, @tz_str export - assess, # Metrics - ReliabilityMetric, LOLE, EUE, - val, stderror, + ReliabilityMetric, + LOLE, + EUE, + val, + stderror, # Simulation specifications - Convolution, SequentialMonteCarlo, + Convolution, + SequentialMonteCarlo, # Result specifications - Shortfall, ShortfallSamples, Surplus, SurplusSamples, - Flow, FlowSamples, Utilization, UtilizationSamples, - StorageEnergy, StorageEnergySamples, - GeneratorStorageEnergy, GeneratorStorageEnergySamples, - GeneratorAvailability, StorageAvailability, - GeneratorStorageAvailability, LineAvailability, + Shortfall, + ShortfallSamples, + Surplus, + SurplusSamples, + Flow, + FlowSamples, + Utilization, + UtilizationSamples, + StorageEnergy, + StorageEnergySamples, + GeneratorStorageEnergy, + GeneratorStorageEnergySamples, + GeneratorAvailability, + StorageAvailability, + GeneratorStorageAvailability, + LineAvailability, # Convenience re-exports - ZonedDateTime, @tz_str + ZonedDateTime, + @tz_str abstract type ReliabilityMetric end abstract type SimulationSpec end abstract type ResultSpec end -abstract type ResultAccumulator{S<:SimulationSpec,R<:ResultSpec} end +abstract type ResultAccumulator{S <: SimulationSpec, R <: ResultSpec} end abstract type Result{ N, # Number of timesteps simulated L, # Length of each simulation timestep @@ -49,8 +63,9 @@ abstract type Result{ } end MeanVariance = Series{ - Number, Tuple{Mean{Float64, EqualWeight}, - Variance{Float64, Float64, EqualWeight}}} + Number, + Tuple{Mean{Float64, EqualWeight}, Variance{Float64, Float64, EqualWeight}}, +} include("metrics.jl") include("results/results.jl") diff --git a/src/PRAS/ResourceAdequacy/metrics.jl b/src/PRAS/ResourceAdequacy/metrics.jl index fc8aa6b..159b6d5 100644 --- a/src/PRAS/ResourceAdequacy/metrics.jl +++ b/src/PRAS/ResourceAdequacy/metrics.jl @@ -1,17 +1,14 @@ struct MeanEstimate - estimate::Float64 standarderror::Float64 function MeanEstimate(est::Real, stderr::Real) - - stderr >= 0 || throw(DomainError(stderr, - "Standard error of the estimate should be non-negative")) + stderr >= 0 || throw( + DomainError(stderr, "Standard error of the estimate should be non-negative"), + ) new(convert(Float64, est), convert(Float64, stderr)) - end - end MeanEstimate(x::Real) = MeanEstimate(x, 0) @@ -27,88 +24,89 @@ val(est::MeanEstimate) = est.estimate stderror(est::MeanEstimate) = est.standarderror Base.isapprox(x::MeanEstimate, y::MeanEstimate) = - isapprox(x.estimate, y.estimate) && - isapprox(x.standarderror, y.standarderror) + isapprox(x.estimate, y.estimate) && isapprox(x.standarderror, y.standarderror) function Base.show(io::IO, x::MeanEstimate) v, s = stringprecision(x) - print(io, v, x.standarderror > 0 ? "±"*s : "") + print(io, v, x.standarderror > 0 ? "±" * s : "") end function stringprecision(x::MeanEstimate) - if iszero(x.standarderror) - v_rounded = @sprintf "%0.5f" x.estimate s_rounded = "0" else - stderr_round = round(x.standarderror, sigdigits=1) digits = floor(Int, log(10, stderr_round)) rounded = round(x.estimate, digits=-digits) - reduced = round(Int, rounded / 10. ^ digits) + reduced = round(Int, rounded / 10.0^digits) v_rounded = string(Decimal(Int(x.estimate < 0), abs(reduced), digits)) s_rounded = string(decimal(stderr_round)) - end return v_rounded, s_rounded - end Base.isapprox(x::ReliabilityMetric, y::ReliabilityMetric) = - isapprox(val(x), val(y)) && isapprox(stderror(x), stderror(y)) + isapprox(val(x), val(y)) && isapprox(stderror(x), stderror(y)) # Loss-of-Load Expectation -struct LOLE{N,L,T<:Period} <: ReliabilityMetric - +struct LOLE{N, L, T <: Period} <: ReliabilityMetric lole::MeanEstimate - function LOLE{N,L,T}(lole::MeanEstimate) where {N,L,T<:Period} - val(lole) >= 0 || throw(DomainError(val, - "$val is not a valid expected count of event-periods")) - new{N,L,T}(lole) + function LOLE{N, L, T}(lole::MeanEstimate) where {N, L, T <: Period} + val(lole) >= 0 || + throw(DomainError(val, "$val is not a valid expected count of event-periods")) + new{N, L, T}(lole) end - end val(x::LOLE) = val(x.lole) stderror(x::LOLE) = stderror(x.lole) -function Base.show(io::IO, x::LOLE{N,L,T}) where {N,L,T} - +function Base.show(io::IO, x::LOLE{N, L, T}) where {N, L, T} t_symbol = unitsymbol(T) - print(io, "LOLE = ", x.lole, " event-", - L == 1 ? t_symbol : "(" * string(L) * t_symbol * ")", "/", - N*L == 1 ? "" : N*L, t_symbol) - + print( + io, + "LOLE = ", + x.lole, + " event-", + L == 1 ? t_symbol : "(" * string(L) * t_symbol * ")", + "/", + N * L == 1 ? "" : N * L, + t_symbol, + ) end # Expected Unserved Energy -struct EUE{N,L,T<:Period,E<:EnergyUnit} <: ReliabilityMetric - +struct EUE{N, L, T <: Period, E <: EnergyUnit} <: ReliabilityMetric eue::MeanEstimate - function EUE{N,L,T,E}(eue::MeanEstimate) where {N,L,T<:Period,E<:EnergyUnit} - val(eue) >= 0 || throw(DomainError( - "$val is not a valid unserved energy expectation")) - new{N,L,T,E}(eue) + function EUE{N, L, T, E}(eue::MeanEstimate) where {N, L, T <: Period, E <: EnergyUnit} + val(eue) >= 0 || + throw(DomainError("$val is not a valid unserved energy expectation")) + new{N, L, T, E}(eue) end - end val(x::EUE) = val(x.eue) stderror(x::EUE) = stderror(x.eue) -function Base.show(io::IO, x::EUE{N,L,T,E}) where {N,L,T,E} - - print(io, "EUE = ", x.eue, " ", - unitsymbol(E), "/", N*L == 1 ? "" : N*L, unitsymbol(T)) - +function Base.show(io::IO, x::EUE{N, L, T, E}) where {N, L, T, E} + print( + io, + "EUE = ", + x.eue, + " ", + unitsymbol(E), + "/", + N * L == 1 ? "" : N * L, + unitsymbol(T), + ) end diff --git a/src/PRAS/ResourceAdequacy/results/availability.jl b/src/PRAS/ResourceAdequacy/results/availability.jl index 774513b..699372b 100644 --- a/src/PRAS/ResourceAdequacy/results/availability.jl +++ b/src/PRAS/ResourceAdequacy/results/availability.jl @@ -1,4 +1,4 @@ -abstract type AbstractAvailabilityResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractAvailabilityResult{N, L, T} <: Result{N, L, T} end # Colon indexing @@ -15,13 +15,11 @@ getindex(x::AbstractAvailabilityResult, ::Colon, ::Colon) = struct GeneratorAvailability <: ResultSpec end -struct GeneratorAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} - +struct GeneratorAvailabilityResult{N, L, T <: Period} <: AbstractAvailabilityResult{N, L, T} generators::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - available::Array{Bool,3} + timestamps::StepRange{ZonedDateTime, T} + available::Array{Bool, 3} end names(x::GeneratorAvailabilityResult) = x.generators @@ -36,13 +34,11 @@ end struct StorageAvailability <: ResultSpec end -struct StorageAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} - +struct StorageAvailabilityResult{N, L, T <: Period} <: AbstractAvailabilityResult{N, L, T} storages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - available::Array{Bool,3} + timestamps::StepRange{ZonedDateTime, T} + available::Array{Bool, 3} end names(x::StorageAvailabilityResult) = x.storages @@ -57,18 +53,21 @@ end struct GeneratorStorageAvailability <: ResultSpec end -struct GeneratorStorageAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} - +struct GeneratorStorageAvailabilityResult{N, L, T <: Period} <: + AbstractAvailabilityResult{N, L, T} generatorstorages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - available::Array{Bool,3} + timestamps::StepRange{ZonedDateTime, T} + available::Array{Bool, 3} end names(x::GeneratorStorageAvailabilityResult) = x.generatorstorages -function getindex(x::GeneratorStorageAvailabilityResult, gs::AbstractString, t::ZonedDateTime) +function getindex( + x::GeneratorStorageAvailabilityResult, + gs::AbstractString, + t::ZonedDateTime, +) i_gs = findfirstunique(x.generatorstorages, gs) i_t = findfirstunique(x.timestamps, t) return vec(x.available[i_gs, i_t, :]) @@ -78,13 +77,11 @@ end struct LineAvailability <: ResultSpec end -struct LineAvailabilityResult{N,L,T<:Period} <: AbstractAvailabilityResult{N,L,T} - +struct LineAvailabilityResult{N, L, T <: Period} <: AbstractAvailabilityResult{N, L, T} lines::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - available::Array{Bool,3} + timestamps::StepRange{ZonedDateTime, T} + available::Array{Bool, 3} end names(x::LineAvailabilityResult) = x.lines diff --git a/src/PRAS/ResourceAdequacy/results/energy.jl b/src/PRAS/ResourceAdequacy/results/energy.jl index b121c4a..689dec6 100644 --- a/src/PRAS/ResourceAdequacy/results/energy.jl +++ b/src/PRAS/ResourceAdequacy/results/energy.jl @@ -1,15 +1,12 @@ -abstract type AbstractEnergyResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractEnergyResult{N, L, T} <: Result{N, L, T} end # Colon indexing -getindex(x::AbstractEnergyResult, ::Colon) = - getindex.(x, x.timestamps) +getindex(x::AbstractEnergyResult, ::Colon) = getindex.(x, x.timestamps) -getindex(x::AbstractEnergyResult, ::Colon, t::ZonedDateTime) = - getindex.(x, names(x), t) +getindex(x::AbstractEnergyResult, ::Colon, t::ZonedDateTime) = getindex.(x, names(x), t) -getindex(x::AbstractEnergyResult, name::String, ::Colon) = - getindex.(x, name, x.timestamps) +getindex(x::AbstractEnergyResult, name::String, ::Colon) = getindex.(x, name, x.timestamps) getindex(x::AbstractEnergyResult, ::Colon, ::Colon) = getindex.(x, names(x), permutedims(x.timestamps)) @@ -18,17 +15,16 @@ getindex(x::AbstractEnergyResult, ::Colon, ::Colon) = struct StorageEnergy <: ResultSpec end -struct StorageEnergyResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} - - nsamples::Union{Int,Nothing} +struct StorageEnergyResult{N, L, T <: Period, E <: EnergyUnit} <: + AbstractEnergyResult{N, L, T} + nsamples::Union{Int, Nothing} storages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} + timestamps::StepRange{ZonedDateTime, T} energy_mean::Matrix{Float64} energy_period_std::Vector{Float64} energy_regionperiod_std::Matrix{Float64} - end names(x::StorageEnergyResult) = x.storages @@ -48,17 +44,16 @@ end struct GeneratorStorageEnergy <: ResultSpec end -struct GeneratorStorageEnergyResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} - - nsamples::Union{Int,Nothing} +struct GeneratorStorageEnergyResult{N, L, T <: Period, E <: EnergyUnit} <: + AbstractEnergyResult{N, L, T} + nsamples::Union{Int, Nothing} generatorstorages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} + timestamps::StepRange{ZonedDateTime, T} energy_mean::Matrix{Float64} energy_period_std::Vector{Float64} energy_regionperiod_std::Matrix{Float64} - end names(x::GeneratorStorageEnergyResult) = x.generatorstorages @@ -78,13 +73,12 @@ end struct StorageEnergySamples <: ResultSpec end -struct StorageEnergySamplesResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} - +struct StorageEnergySamplesResult{N, L, T <: Period, E <: EnergyUnit} <: + AbstractEnergyResult{N, L, T} storages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - energy::Array{Int,3} + timestamps::StepRange{ZonedDateTime, T} + energy::Array{Int, 3} end names(x::StorageEnergySamplesResult) = x.storages @@ -104,13 +98,12 @@ end struct GeneratorStorageEnergySamples <: ResultSpec end -struct GeneratorStorageEnergySamplesResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractEnergyResult{N,L,T} - +struct GeneratorStorageEnergySamplesResult{N, L, T <: Period, E <: EnergyUnit} <: + AbstractEnergyResult{N, L, T} generatorstorages::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - energy::Array{Int,3} + timestamps::StepRange{ZonedDateTime, T} + energy::Array{Int, 3} end names(x::GeneratorStorageEnergySamplesResult) = x.generatorstorages @@ -120,7 +113,11 @@ function getindex(x::GeneratorStorageEnergySamplesResult, t::ZonedDateTime) return vec(sum(view(x.energy, :, i_t, :), dims=1)) end -function getindex(x::GeneratorStorageEnergySamplesResult, gs::AbstractString, t::ZonedDateTime) +function getindex( + x::GeneratorStorageEnergySamplesResult, + gs::AbstractString, + t::ZonedDateTime, +) i_gs = findfirstunique(x.generatorstorages, gs) i_t = findfirstunique(x.timestamps, t) return vec(x.energy[i_gs, i_t, :]) diff --git a/src/PRAS/ResourceAdequacy/results/flow.jl b/src/PRAS/ResourceAdequacy/results/flow.jl index d8c11fc..4e33773 100644 --- a/src/PRAS/ResourceAdequacy/results/flow.jl +++ b/src/PRAS/ResourceAdequacy/results/flow.jl @@ -1,15 +1,13 @@ struct Flow <: ResultSpec end -abstract type AbstractFlowResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractFlowResult{N, L, T} <: Result{N, L, T} end # Colon indexing -getindex(x::AbstractFlowResult, ::Colon) = - getindex.(x, x.interfaces) +getindex(x::AbstractFlowResult, ::Colon) = getindex.(x, x.interfaces) -getindex(x::AbstractFlowResult, ::Colon, t::ZonedDateTime) = - getindex.(x, x.interfaces, t) +getindex(x::AbstractFlowResult, ::Colon, t::ZonedDateTime) = getindex.(x, x.interfaces, t) -getindex(x::AbstractFlowResult, i::Pair{<:AbstractString,<:AbstractString}, ::Colon) = +getindex(x::AbstractFlowResult, i::Pair{<:AbstractString, <:AbstractString}, ::Colon) = getindex.(x, i, x.timestamps) getindex(x::AbstractFlowResult, ::Colon, ::Colon) = @@ -17,26 +15,28 @@ getindex(x::AbstractFlowResult, ::Colon, ::Colon) = # Sample-averaged flow data -struct FlowResult{N,L,T<:Period,P<:PowerUnit} <: AbstractFlowResult{N,L,T} - - nsamples::Union{Int,Nothing} - interfaces::Vector{Pair{String,String}} - timestamps::StepRange{ZonedDateTime,T} +struct FlowResult{N, L, T <: Period, P <: PowerUnit} <: AbstractFlowResult{N, L, T} + nsamples::Union{Int, Nothing} + interfaces::Vector{Pair{String, String}} + timestamps::StepRange{ZonedDateTime, T} flow_mean::Matrix{Float64} flow_interface_std::Vector{Float64} flow_interfaceperiod_std::Matrix{Float64} - end -function getindex(x::FlowResult, i::Pair{<:AbstractString,<:AbstractString}) +function getindex(x::FlowResult, i::Pair{<:AbstractString, <:AbstractString}) i_i, reverse = findfirstunique_directional(x.interfaces, i) flow = mean(view(x.flow_mean, i_i, :)) return reverse ? -flow : flow, x.flow_interface_std[i_i] end -function getindex(x::FlowResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) +function getindex( + x::FlowResult, + i::Pair{<:AbstractString, <:AbstractString}, + t::ZonedDateTime, +) i_i, reverse = findfirstunique_directional(x.interfaces, i) i_t = findfirstunique(x.timestamps, t) flow = x.flow_mean[i_i, i_t] @@ -47,23 +47,24 @@ end struct FlowSamples <: ResultSpec end -struct FlowSamplesResult{N,L,T<:Period,P<:PowerUnit} <: AbstractFlowResult{N,L,T} - - interfaces::Vector{Pair{String,String}} - timestamps::StepRange{ZonedDateTime,T} - - flow::Array{Int,3} +struct FlowSamplesResult{N, L, T <: Period, P <: PowerUnit} <: AbstractFlowResult{N, L, T} + interfaces::Vector{Pair{String, String}} + timestamps::StepRange{ZonedDateTime, T} + flow::Array{Int, 3} end -function getindex(x::FlowSamplesResult, i::Pair{<:AbstractString,<:AbstractString}) +function getindex(x::FlowSamplesResult, i::Pair{<:AbstractString, <:AbstractString}) i_i, reverse = findfirstunique_directional(x.interfaces, i) flow = vec(mean(view(x.flow, i_i, :, :), dims=1)) return reverse ? -flow : flow end - -function getindex(x::FlowSamplesResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) +function getindex( + x::FlowSamplesResult, + i::Pair{<:AbstractString, <:AbstractString}, + t::ZonedDateTime, +) i_i, reverse = findfirstunique_directional(x.interfaces, i) i_t = findfirstunique(x.timestamps, t) flow = vec(x.flow[i_i, i_t, :]) diff --git a/src/PRAS/ResourceAdequacy/results/results.jl b/src/PRAS/ResourceAdequacy/results/results.jl index 895da22..ce3ee6f 100644 --- a/src/PRAS/ResourceAdequacy/results/results.jl +++ b/src/PRAS/ResourceAdequacy/results/results.jl @@ -9,23 +9,21 @@ include("availability.jl") include("energy.jl") function resultchannel( - method::SimulationSpec, results::T, threads::Int -) where T <: Tuple{Vararg{ResultSpec}} - + method::SimulationSpec, + results::T, + threads::Int, +) where {T <: Tuple{Vararg{ResultSpec}}} types = accumulatortype.(method, results) return Channel{Tuple{types...}}(threads) - end -merge!(xs::T, ys::T) where T <: Tuple{Vararg{ResultAccumulator}} = - foreach(merge!, xs, ys) +merge!(xs::T, ys::T) where {T <: Tuple{Vararg{ResultAccumulator}}} = foreach(merge!, xs, ys) function finalize( results::Channel{<:Tuple{Vararg{ResultAccumulator}}}, - system::SystemModel{N,L,T,P,E}, - threads::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + threads::Int, +) where {N, L, T, P, E} total_result = take!(results) for _ in 2:threads @@ -35,5 +33,4 @@ function finalize( close(results) return finalize.(total_result, system) - end diff --git a/src/PRAS/ResourceAdequacy/results/shortfall.jl b/src/PRAS/ResourceAdequacy/results/shortfall.jl index 2eb8935..8531327 100644 --- a/src/PRAS/ResourceAdequacy/results/shortfall.jl +++ b/src/PRAS/ResourceAdequacy/results/shortfall.jl @@ -1,10 +1,9 @@ struct Shortfall <: ResultSpec end -abstract type AbstractShortfallResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractShortfallResult{N, L, T} <: Result{N, L, T} end # Colon indexing -getindex(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = - getindex.(x, x.regions, t) +getindex(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = getindex.(x, x.regions, t) getindex(x::AbstractShortfallResult, r::AbstractString, ::Colon) = getindex.(x, r, x.timestamps) @@ -12,33 +11,27 @@ getindex(x::AbstractShortfallResult, r::AbstractString, ::Colon) = getindex(x::AbstractShortfallResult, ::Colon, ::Colon) = getindex.(x, x.regions, permutedims(x.timestamps)) +LOLE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = LOLE.(x, x.regions, t) -LOLE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = - LOLE.(x, x.regions, t) - -LOLE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = - LOLE.(x, r, x.timestamps) +LOLE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = LOLE.(x, r, x.timestamps) LOLE(x::AbstractShortfallResult, ::Colon, ::Colon) = LOLE.(x, x.regions, permutedims(x.timestamps)) +EUE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = EUE.(x, x.regions, t) -EUE(x::AbstractShortfallResult, ::Colon, t::ZonedDateTime) = - EUE.(x, x.regions, t) - -EUE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = - EUE.(x, r, x.timestamps) +EUE(x::AbstractShortfallResult, r::AbstractString, ::Colon) = EUE.(x, r, x.timestamps) EUE(x::AbstractShortfallResult, ::Colon, ::Colon) = EUE.(x, x.regions, permutedims(x.timestamps)) # Sample-averaged shortfall data -struct ShortfallResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractShortfallResult{N,L,T} - - nsamples::Union{Int,Nothing} +struct ShortfallResult{N, L, T <: Period, E <: EnergyUnit} <: + AbstractShortfallResult{N, L, T} + nsamples::Union{Int, Nothing} regions::Vector{String} - timestamps::StepRange{ZonedDateTime,T} + timestamps::StepRange{ZonedDateTime, T} eventperiod_mean::Float64 eventperiod_std::Float64 @@ -52,7 +45,6 @@ struct ShortfallResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractShortfallResult{N eventperiod_regionperiod_mean::Matrix{Float64} eventperiod_regionperiod_std::Matrix{Float64} - shortfall_mean::Matrix{Float64} # r x t shortfall_std::Float64 @@ -60,10 +52,10 @@ struct ShortfallResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractShortfallResult{N shortfall_period_std::Vector{Float64} shortfall_regionperiod_std::Matrix{Float64} - function ShortfallResult{N,L,T,E}( - nsamples::Union{Int,Nothing}, + function ShortfallResult{N, L, T, E}( + nsamples::Union{Int, Nothing}, regions::Vector{String}, - timestamps::StepRange{ZonedDateTime,T}, + timestamps::StepRange{ZonedDateTime, T}, eventperiod_mean::Float64, eventperiod_std::Float64, eventperiod_region_mean::Vector{Float64}, @@ -76,40 +68,47 @@ struct ShortfallResult{N,L,T<:Period,E<:EnergyUnit} <: AbstractShortfallResult{N shortfall_std::Float64, shortfall_region_std::Vector{Float64}, shortfall_period_std::Vector{Float64}, - shortfall_regionperiod_std::Matrix{Float64} - ) where {N,L,T<:Period,E<:EnergyUnit} - - isnothing(nsamples) || nsamples > 0 || + shortfall_regionperiod_std::Matrix{Float64}, + ) where {N, L, T <: Period, E <: EnergyUnit} + isnothing(nsamples) || + nsamples > 0 || throw(DomainError("Sample count must be positive or `nothing`.")) - length(timestamps) == N || error("The provided timestamp range does not match the simulation length") nregions = length(regions) length(eventperiod_region_mean) == nregions && - length(eventperiod_region_std) == nregions && - length(eventperiod_period_mean) == N && - length(eventperiod_period_std) == N && - size(eventperiod_regionperiod_mean) == (nregions, N) && - size(eventperiod_regionperiod_std) == (nregions, N) && - length(shortfall_region_std) == nregions && - length(shortfall_period_std) == N && - size(shortfall_regionperiod_std) == (nregions, N) || + length(eventperiod_region_std) == nregions && + length(eventperiod_period_mean) == N && + length(eventperiod_period_std) == N && + size(eventperiod_regionperiod_mean) == (nregions, N) && + size(eventperiod_regionperiod_std) == (nregions, N) && + length(shortfall_region_std) == nregions && + length(shortfall_period_std) == N && + size(shortfall_regionperiod_std) == (nregions, N) || error("Inconsistent input data sizes") - new{N,L,T,E}(nsamples, regions, timestamps, - eventperiod_mean, eventperiod_std, - eventperiod_region_mean, eventperiod_region_std, - eventperiod_period_mean, eventperiod_period_std, - eventperiod_regionperiod_mean, eventperiod_regionperiod_std, - shortfall_mean, shortfall_std, - shortfall_region_std, shortfall_period_std, - shortfall_regionperiod_std) - + new{N, L, T, E}( + nsamples, + regions, + timestamps, + eventperiod_mean, + eventperiod_std, + eventperiod_region_mean, + eventperiod_region_std, + eventperiod_period_mean, + eventperiod_period_std, + eventperiod_regionperiod_mean, + eventperiod_regionperiod_std, + shortfall_mean, + shortfall_std, + shortfall_region_std, + shortfall_period_std, + shortfall_regionperiod_std, + ) end - end function getindex(x::ShortfallResult) @@ -132,126 +131,147 @@ function getindex(x::ShortfallResult, r::AbstractString, t::ZonedDateTime) return x.shortfall_mean[i_r, i_t], x.shortfall_regionperiod_std[i_r, i_t] end +LOLE(x::ShortfallResult{N, L, T}) where {N, L, T} = + LOLE{N, L, T}(MeanEstimate(x.eventperiod_mean, x.eventperiod_std, x.nsamples)) -LOLE(x::ShortfallResult{N,L,T}) where {N,L,T} = - LOLE{N,L,T}(MeanEstimate(x.eventperiod_mean, - x.eventperiod_std, - x.nsamples)) - -function LOLE(x::ShortfallResult{N,L,T}, r::AbstractString) where {N,L,T} +function LOLE(x::ShortfallResult{N, L, T}, r::AbstractString) where {N, L, T} i_r = findfirstunique(x.regions, r) - return LOLE{N,L,T}(MeanEstimate(x.eventperiod_region_mean[i_r], - x.eventperiod_region_std[i_r], - x.nsamples)) + return LOLE{N, L, T}( + MeanEstimate( + x.eventperiod_region_mean[i_r], + x.eventperiod_region_std[i_r], + x.nsamples, + ), + ) end -function LOLE(x::ShortfallResult{N,L,T}, t::ZonedDateTime) where {N,L,T} +function LOLE(x::ShortfallResult{N, L, T}, t::ZonedDateTime) where {N, L, T} i_t = findfirstunique(x.timestamps, t) - return LOLE{1,L,T}(MeanEstimate(x.eventperiod_period_mean[i_t], - x.eventperiod_period_std[i_t], - x.nsamples)) + return LOLE{1, L, T}( + MeanEstimate( + x.eventperiod_period_mean[i_t], + x.eventperiod_period_std[i_t], + x.nsamples, + ), + ) end -function LOLE(x::ShortfallResult{N,L,T}, r::AbstractString, t::ZonedDateTime) where {N,L,T} +function LOLE( + x::ShortfallResult{N, L, T}, + r::AbstractString, + t::ZonedDateTime, +) where {N, L, T} i_r = findfirstunique(x.regions, r) i_t = findfirstunique(x.timestamps, t) - return LOLE{1,L,T}(MeanEstimate(x.eventperiod_regionperiod_mean[i_r, i_t], - x.eventperiod_regionperiod_std[i_r, i_t], - x.nsamples)) + return LOLE{1, L, T}( + MeanEstimate( + x.eventperiod_regionperiod_mean[i_r, i_t], + x.eventperiod_regionperiod_std[i_r, i_t], + x.nsamples, + ), + ) end +EUE(x::ShortfallResult{N, L, T, E}) where {N, L, T, E} = + EUE{N, L, T, E}(MeanEstimate(x[]..., x.nsamples)) -EUE(x::ShortfallResult{N,L,T,E}) where {N,L,T,E} = - EUE{N,L,T,E}(MeanEstimate(x[]..., x.nsamples)) - -EUE(x::ShortfallResult{N,L,T,E}, r::AbstractString) where {N,L,T,E} = - EUE{N,L,T,E}(MeanEstimate(x[r]..., x.nsamples)) +EUE(x::ShortfallResult{N, L, T, E}, r::AbstractString) where {N, L, T, E} = + EUE{N, L, T, E}(MeanEstimate(x[r]..., x.nsamples)) -EUE(x::ShortfallResult{N,L,T,E}, t::ZonedDateTime) where {N,L,T,E} = - EUE{1,L,T,E}(MeanEstimate(x[t]..., x.nsamples)) +EUE(x::ShortfallResult{N, L, T, E}, t::ZonedDateTime) where {N, L, T, E} = + EUE{1, L, T, E}(MeanEstimate(x[t]..., x.nsamples)) -EUE(x::ShortfallResult{N,L,T,E}, r::AbstractString, t::ZonedDateTime) where {N,L,T,E} = - EUE{1,L,T,E}(MeanEstimate(x[r, t]..., x.nsamples)) +EUE( + x::ShortfallResult{N, L, T, E}, + r::AbstractString, + t::ZonedDateTime, +) where {N, L, T, E} = EUE{1, L, T, E}(MeanEstimate(x[r, t]..., x.nsamples)) # Full shortfall data struct ShortfallSamples <: ResultSpec end -struct ShortfallSamplesResult{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractShortfallResult{N,L,T} - +struct ShortfallSamplesResult{N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} <: + AbstractShortfallResult{N, L, T} regions::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - shortfall::Array{Int,3} # r x t x s + timestamps::StepRange{ZonedDateTime, T} + shortfall::Array{Int, 3} # r x t x s end -function getindex( - x::ShortfallSamplesResult{N,L,T,P,E} -) where {N,L,T,P,E} +function getindex(x::ShortfallSamplesResult{N, L, T, P, E}) where {N, L, T, P, E} p2e = conversionfactor(L, T, P, E) return vec(p2e * sum(x.shortfall, dims=1:2)) end function getindex( - x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString -) where {N,L,T,P,E} + x::ShortfallSamplesResult{N, L, T, P, E}, + r::AbstractString, +) where {N, L, T, P, E} i_r = findfirstunique(x.regions, r) p2e = conversionfactor(L, T, P, E) return vec(p2e * sum(view(x.shortfall, i_r, :, :), dims=1)) end function getindex( - x::ShortfallSamplesResult{N,L,T,P,E}, t::ZonedDateTime -) where {N,L,T,P,E} + x::ShortfallSamplesResult{N, L, T, P, E}, + t::ZonedDateTime, +) where {N, L, T, P, E} i_t = findfirstunique(x.timestamps, t) p2e = conversionfactor(L, T, P, E) return vec(p2e * sum(view(x.shortfall, :, i_t, :), dims=1)) end function getindex( - x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString, t::ZonedDateTime -) where {N,L,T,P,E} + x::ShortfallSamplesResult{N, L, T, P, E}, + r::AbstractString, + t::ZonedDateTime, +) where {N, L, T, P, E} i_r = findfirstunique(x.regions, r) i_t = findfirstunique(x.timestamps, t) p2e = conversionfactor(L, T, P, E) return vec(p2e * x.shortfall[i_r, i_t, :]) end - -function LOLE(x::ShortfallSamplesResult{N,L,T}) where {N,L,T} +function LOLE(x::ShortfallSamplesResult{N, L, T}) where {N, L, T} eventperiods = sum(sum(x.shortfall, dims=1) .> 0, dims=2) - return LOLE{N,L,T}(MeanEstimate(eventperiods)) + return LOLE{N, L, T}(MeanEstimate(eventperiods)) end -function LOLE(x::ShortfallSamplesResult{N,L,T}, r::AbstractString) where {N,L,T} +function LOLE(x::ShortfallSamplesResult{N, L, T}, r::AbstractString) where {N, L, T} i_r = findfirstunique(x.regions, r) eventperiods = sum(view(x.shortfall, i_r, :, :) .> 0, dims=1) - return LOLE{N,L,T}(MeanEstimate(eventperiods)) + return LOLE{N, L, T}(MeanEstimate(eventperiods)) end -function LOLE(x::ShortfallSamplesResult{N,L,T}, t::ZonedDateTime) where {N,L,T} +function LOLE(x::ShortfallSamplesResult{N, L, T}, t::ZonedDateTime) where {N, L, T} i_t = findfirstunique(x.timestamps, t) eventperiods = sum(view(x.shortfall, :, i_t, :), dims=1) .> 0 - return LOLE{1,L,T}(MeanEstimate(eventperiods)) + return LOLE{1, L, T}(MeanEstimate(eventperiods)) end -function LOLE(x::ShortfallSamplesResult{N,L,T}, r::AbstractString, t::ZonedDateTime) where {N,L,T} +function LOLE( + x::ShortfallSamplesResult{N, L, T}, + r::AbstractString, + t::ZonedDateTime, +) where {N, L, T} i_r = findfirstunique(x.regions, r) i_t = findfirstunique(x.timestamps, t) eventperiods = view(x.shortfall, i_r, i_t, :) .> 0 - return LOLE{1,L,T}(MeanEstimate(eventperiods)) + return LOLE{1, L, T}(MeanEstimate(eventperiods)) end +EUE(x::ShortfallSamplesResult{N, L, T, P, E}) where {N, L, T, P, E} = + EUE{N, L, T, E}(MeanEstimate(x[])) -EUE(x::ShortfallSamplesResult{N,L,T,P,E}) where {N,L,T,P,E} = - EUE{N,L,T,E}(MeanEstimate(x[])) - -EUE(x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString) where {N,L,T,P,E} = - EUE{N,L,T,E}(MeanEstimate(x[r])) +EUE(x::ShortfallSamplesResult{N, L, T, P, E}, r::AbstractString) where {N, L, T, P, E} = + EUE{N, L, T, E}(MeanEstimate(x[r])) -EUE(x::ShortfallSamplesResult{N,L,T,P,E}, t::ZonedDateTime) where {N,L,T,P,E} = - EUE{1,L,T,E}(MeanEstimate(x[t])) +EUE(x::ShortfallSamplesResult{N, L, T, P, E}, t::ZonedDateTime) where {N, L, T, P, E} = + EUE{1, L, T, E}(MeanEstimate(x[t])) -EUE(x::ShortfallSamplesResult{N,L,T,P,E}, r::AbstractString, t::ZonedDateTime) where {N,L,T,P,E} = - EUE{1,L,T,E}(MeanEstimate(x[r, t])) +EUE( + x::ShortfallSamplesResult{N, L, T, P, E}, + r::AbstractString, + t::ZonedDateTime, +) where {N, L, T, P, E} = EUE{1, L, T, E}(MeanEstimate(x[r, t])) diff --git a/src/PRAS/ResourceAdequacy/results/surplus.jl b/src/PRAS/ResourceAdequacy/results/surplus.jl index a3ab03c..5c7014e 100644 --- a/src/PRAS/ResourceAdequacy/results/surplus.jl +++ b/src/PRAS/ResourceAdequacy/results/surplus.jl @@ -1,13 +1,11 @@ struct Surplus <: ResultSpec end -abstract type AbstractSurplusResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractSurplusResult{N, L, T} <: Result{N, L, T} end # Colon indexing -getindex(x::AbstractSurplusResult, ::Colon) = - getindex.(x, x.timestamps) +getindex(x::AbstractSurplusResult, ::Colon) = getindex.(x, x.timestamps) -getindex(x::AbstractSurplusResult, ::Colon, t::ZonedDateTime) = - getindex.(x, x.regions, t) +getindex(x::AbstractSurplusResult, ::Colon, t::ZonedDateTime) = getindex.(x, x.regions, t) getindex(x::AbstractSurplusResult, r::AbstractString, ::Colon) = getindex.(x, r, x.timestamps) @@ -17,17 +15,15 @@ getindex(x::AbstractSurplusResult, ::Colon, ::Colon) = # Sample-averaged surplus data -struct SurplusResult{N,L,T<:Period,P<:PowerUnit} <: AbstractSurplusResult{N,L,T} - - nsamples::Union{Int,Nothing} +struct SurplusResult{N, L, T <: Period, P <: PowerUnit} <: AbstractSurplusResult{N, L, T} + nsamples::Union{Int, Nothing} regions::Vector{String} - timestamps::StepRange{ZonedDateTime,T} + timestamps::StepRange{ZonedDateTime, T} surplus_mean::Matrix{Float64} surplus_period_std::Vector{Float64} surplus_regionperiod_std::Matrix{Float64} - end function getindex(x::SurplusResult, t::ZonedDateTime) @@ -45,13 +41,12 @@ end struct SurplusSamples <: ResultSpec end -struct SurplusSamplesResult{N,L,T<:Period,P<:PowerUnit} <: AbstractSurplusResult{N,L,T} - +struct SurplusSamplesResult{N, L, T <: Period, P <: PowerUnit} <: + AbstractSurplusResult{N, L, T} regions::Vector{String} - timestamps::StepRange{ZonedDateTime,T} - - surplus::Array{Int,3} + timestamps::StepRange{ZonedDateTime, T} + surplus::Array{Int, 3} end function getindex(x::SurplusSamplesResult, t::ZonedDateTime) diff --git a/src/PRAS/ResourceAdequacy/results/utilization.jl b/src/PRAS/ResourceAdequacy/results/utilization.jl index e17e007..21b8a8f 100644 --- a/src/PRAS/ResourceAdequacy/results/utilization.jl +++ b/src/PRAS/ResourceAdequacy/results/utilization.jl @@ -1,41 +1,45 @@ struct Utilization <: ResultSpec end -abstract type AbstractUtilizationResult{N,L,T} <: Result{N,L,T} end +abstract type AbstractUtilizationResult{N, L, T} <: Result{N, L, T} end # Colon indexing -getindex(x::AbstractUtilizationResult, ::Colon) = - getindex.(x, x.interfaces) +getindex(x::AbstractUtilizationResult, ::Colon) = getindex.(x, x.interfaces) getindex(x::AbstractUtilizationResult, ::Colon, t::ZonedDateTime) = getindex.(x, x.interfaces, t) -getindex(x::AbstractUtilizationResult, i::Pair{<:AbstractString,<:AbstractString}, ::Colon) = - getindex.(x, i, x.timestamps) +getindex( + x::AbstractUtilizationResult, + i::Pair{<:AbstractString, <:AbstractString}, + ::Colon, +) = getindex.(x, i, x.timestamps) getindex(x::AbstractUtilizationResult, ::Colon, ::Colon) = getindex.(x, x.interfaces, permutedims(x.timestamps)) # Sample-averaged utilization data -struct UtilizationResult{N,L,T<:Period} <: AbstractUtilizationResult{N,L,T} - - nsamples::Union{Int,Nothing} - interfaces::Vector{Pair{String,String}} - timestamps::StepRange{ZonedDateTime,T} +struct UtilizationResult{N, L, T <: Period} <: AbstractUtilizationResult{N, L, T} + nsamples::Union{Int, Nothing} + interfaces::Vector{Pair{String, String}} + timestamps::StepRange{ZonedDateTime, T} utilization_mean::Matrix{Float64} utilization_interface_std::Vector{Float64} utilization_interfaceperiod_std::Matrix{Float64} - end -function getindex(x::UtilizationResult, i::Pair{<:AbstractString,<:AbstractString}) +function getindex(x::UtilizationResult, i::Pair{<:AbstractString, <:AbstractString}) i_i, _ = findfirstunique_directional(x.interfaces, i) return mean(view(x.utilization_mean, i_i, :)), x.utilization_interface_std[i_i] end -function getindex(x::UtilizationResult, i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) +function getindex( + x::UtilizationResult, + i::Pair{<:AbstractString, <:AbstractString}, + t::ZonedDateTime, +) i_i, _ = findfirstunique_directional(x.interfaces, i) i_t = findfirstunique(x.timestamps, t) return x.utilization_mean[i_i, i_t], x.utilization_interfaceperiod_std[i_i, i_t] @@ -45,24 +49,23 @@ end struct UtilizationSamples <: ResultSpec end -struct UtilizationSamplesResult{N,L,T<:Period} <: AbstractUtilizationResult{N,L,T} - - interfaces::Vector{Pair{String,String}} - timestamps::StepRange{ZonedDateTime,T} - - utilization::Array{Float64,3} +struct UtilizationSamplesResult{N, L, T <: Period} <: AbstractUtilizationResult{N, L, T} + interfaces::Vector{Pair{String, String}} + timestamps::StepRange{ZonedDateTime, T} + utilization::Array{Float64, 3} end -function getindex(x::UtilizationSamplesResult, - i::Pair{<:AbstractString,<:AbstractString}) +function getindex(x::UtilizationSamplesResult, i::Pair{<:AbstractString, <:AbstractString}) i_i, _ = findfirstunique_directional(x.interfaces, i) return vec(mean(view(x.utilization, i_i, :, :), dims=1)) end - -function getindex(x::UtilizationSamplesResult, - i::Pair{<:AbstractString,<:AbstractString}, t::ZonedDateTime) +function getindex( + x::UtilizationSamplesResult, + i::Pair{<:AbstractString, <:AbstractString}, + t::ZonedDateTime, +) i_i, _ = findfirstunique_directional(x.interfaces, i) i_t = findfirstunique(x.timestamps, t) return vec(x.utilization[i_i, i_t, :]) diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl index 4b0224b..6944880 100644 --- a/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/Convolution.jl @@ -1,21 +1,17 @@ include("conv.jl") struct Convolution <: SimulationSpec - verbose::Bool threaded::Bool - Convolution(;verbose::Bool=false, threaded::Bool=true) = - new(verbose, threaded) - + Convolution(; verbose::Bool=false, threaded::Bool=true) = new(verbose, threaded) end function assess( system::SystemModel{N}, method::Convolution, - resultspecs::ResultSpec... + resultspecs::ResultSpec..., ) where {N} - nregions = length(system.regions) nstors = length(system.storages) ngenstors = length(system.generatorstorages) @@ -31,18 +27,19 @@ function assess( nstors > 0 && push!(resources, "$nstors Storage") ngenstors > 0 && push!(resources, "$ngenstors GeneratorStorage") @warn "$method is a non-sequential simulation method. " * - "The system's " * join(resources, " and ") * " resources " * + "The system's " * + join(resources, " and ") * + " resources " * "will be ignored in this assessment." end threads = nthreads() - periods = Channel{Int}(2*threads) + periods = Channel{Int}(2 * threads) results = resultchannel(method, resultspecs, threads) @spawn makeperiods(periods, N) if method.threaded - if (threads == 1) @warn "It looks like you haven't configured JULIA_NUM_THREADS before you started the julia repl. \n If you want to use multi-threading, stop the execution and start your julia repl using : \n julia --project --threads auto" end @@ -55,7 +52,6 @@ function assess( end return finalize(results, system, method.threaded ? threads : 1) - end function makeperiods(periods::Channel{Int}, N::Int) @@ -66,23 +62,20 @@ function makeperiods(periods::Channel{Int}, N::Int) end function assess( - system::SystemModel{N,L,T,P,E}, method::Convolution, + system::SystemModel{N, L, T, P, E}, + method::Convolution, periods::Channel{Int}, results::Channel{<:Tuple{Vararg{ResultAccumulator{Convolution}}}}, - resultspecs::ResultSpec... -) where {N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} - + resultspecs::ResultSpec..., +) where {N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} accs = accumulator.(system, method, resultspecs) for t in periods - distr = CapacityDistribution(system, t) foreach(acc -> record!(acc, t, distr), accs) - end put!(results, accs) - end include("result_shortfall.jl") diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl index b2892f1..033d0d2 100644 --- a/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/conv.jl @@ -1,8 +1,6 @@ -CapacityDistribution = - DiscreteNonParametric{Int,Float64,Vector{Int},Vector{Float64}} +CapacityDistribution = DiscreteNonParametric{Int, Float64, Vector{Int}, Vector{Float64}} function (::Type{CapacityDistribution})(system::SystemModel, t::Int) - capacities = system.generators.capacity[:, t] μ = system.generators.μ[:, t] @@ -13,88 +11,90 @@ function (::Type{CapacityDistribution})(system::SystemModel, t::Int) support(result) .-= colsum(system.regions.load, t) return result - end function assess(distr::CapacityDistribution) - xs = support(distr) ps = probs(distr) i = 1 - lolp = 0. - eul = 0. + lolp = 0.0 + eul = 0.0 while i <= length(xs) - - xs[i] >= 0 && break - lolp += ps[i] - eul -= ps[i] * xs[i] - i += 1 - + xs[i] >= 0 && break + lolp += ps[i] + eul -= ps[i] * xs[i] + i += 1 end return lolp, eul - end function surplus(distr::CapacityDistribution) - xs = support(distr) ps = probs(distr) i = 1 - es = 0. + es = 0.0 for i in 1:length(xs) - xs[i] <= 0 && continue - es += ps[i] * xs[i] + xs[i] <= 0 && continue + es += ps[i] * xs[i] end return es - end function spconv(hvsraw::AbstractVector{Int}, hpsraw::AbstractVector{Float64}) - zeroidxs = hvsraw .!= 0 hvs = hvsraw[zeroidxs] hps = hpsraw[zeroidxs] - length(hvs) == 0 && - return DiscreteNonParametric([0], [1.], check_args=false) + length(hvs) == 0 && return DiscreteNonParametric([0], [1.0], check_args=false) max_n = sum(hvs) + 1 - current_probs = Vector{Float64}(undef, max_n) - prev_probs = Vector{Float64}(undef, max_n) + current_probs = Vector{Float64}(undef, max_n) + prev_probs = Vector{Float64}(undef, max_n) current_values = Vector{Int}(undef, max_n) - prev_values = Vector{Int}(undef, max_n) + prev_values = Vector{Int}(undef, max_n) current_n = 2 current_values[1:current_n] = [0, hvs[1]] - current_probs[1:current_n] = [1 - hps[1], hps[1]] + current_probs[1:current_n] = [1 - hps[1], hps[1]] for (hv, hp) in zip(hvs[2:end], hps[2:end]) - current_values, current_probs, current_n, prev_values, prev_probs = - spconv!(prev_values, prev_probs, hv, hp, - current_values, current_probs, current_n) + current_values, current_probs, current_n, prev_values, prev_probs = spconv!( + prev_values, + prev_probs, + hv, + hp, + current_values, + current_probs, + current_n, + ) end resize!(current_values, current_n) resize!(current_probs, current_n) - nonzeroprob_idxs = findall(x -> x>0, current_probs) + nonzeroprob_idxs = findall(x -> x > 0, current_probs) return DiscreteNonParametric( current_values[nonzeroprob_idxs], current_probs[nonzeroprob_idxs], - check_args=false) - + check_args=false, + ) end -function spconv!(y_values::Vector{Int}, y_probs::Vector{Float64}, - h_value::Int, h_prob::Float64, - x_values::Vector{Int}, x_probs::Vector{Float64}, nx::Int) - +function spconv!( + y_values::Vector{Int}, + y_probs::Vector{Float64}, + h_value::Int, + h_prob::Float64, + x_values::Vector{Int}, + x_probs::Vector{Float64}, + nx::Int, +) h_q = 1 - h_prob ix = ixsh = 1 @@ -102,7 +102,6 @@ function spconv!(y_values::Vector{Int}, y_probs::Vector{Float64}, lastval = -1 @inbounds while ix <= nx - x = x_values[ix] xsh = x_values[ixsh] + h_value @@ -135,9 +134,7 @@ function spconv!(y_values::Vector{Int}, y_probs::Vector{Float64}, @fastmath y_probs[iy] = h_prob * x_probs[ixsh] lastval = xsh ixsh += 1 - end - end @inbounds while ixsh <= nx @@ -148,5 +145,4 @@ function spconv!(y_values::Vector{Int}, y_probs::Vector{Float64}, end return y_values, y_probs, iy, x_values, x_probs - end diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl index 9821b65..538d6c3 100644 --- a/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/result_shortfall.jl @@ -1,18 +1,12 @@ -struct ConvolutionShortfallAccumulator <: ResultAccumulator{Convolution,Shortfall} - +struct ConvolutionShortfallAccumulator <: ResultAccumulator{Convolution, Shortfall} lolps::Vector{Float64} euls::Vector{Float64} - end -function merge!( - x::ConvolutionShortfallAccumulator, y::ConvolutionShortfallAccumulator -) - +function merge!(x::ConvolutionShortfallAccumulator, y::ConvolutionShortfallAccumulator) x.lolps .+= y.lolps x.euls .+= y.euls return - end accumulatortype(::Convolution, ::Shortfall) = ConvolutionShortfallAccumulator @@ -20,36 +14,41 @@ accumulatortype(::Convolution, ::Shortfall) = ConvolutionShortfallAccumulator accumulator(::SystemModel{N}, ::Convolution, ::Shortfall) where {N} = ConvolutionShortfallAccumulator(zeros(N), zeros(N)) -function record!( - acc::ConvolutionShortfallAccumulator, - t::Int, distr::CapacityDistribution -) - +function record!(acc::ConvolutionShortfallAccumulator, t::Int, distr::CapacityDistribution) lolp, eul = assess(distr) acc.lolps[t] = lolp acc.euls[t] = eul return - end function finalize( acc::ConvolutionShortfallAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} lole = sum(acc.lolps) - p2e = conversionfactor(L,T,P,E) + p2e = conversionfactor(L, T, P, E) eues = acc.euls .* p2e eue = sum(eues) allzeros = zeros(length(acc.lolps)) - return ShortfallResult{N,L,T,E}( - nothing, ["[PRAS] Entire System"], system.timestamps, - lole, 0., [lole], [0.], acc.lolps, allzeros, - reshape(acc.lolps, 1, :), reshape(allzeros, 1, :), - reshape(eues, 1, :), 0., [0.], allzeros, reshape(allzeros, 1, :) + return ShortfallResult{N, L, T, E}( + nothing, + ["[PRAS] Entire System"], + system.timestamps, + lole, + 0.0, + [lole], + [0.0], + acc.lolps, + allzeros, + reshape(acc.lolps, 1, :), + reshape(allzeros, 1, :), + reshape(eues, 1, :), + 0.0, + [0.0], + allzeros, + reshape(allzeros, 1, :), ) - end diff --git a/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl b/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl index 2ff4763..a3861b4 100644 --- a/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl +++ b/src/PRAS/ResourceAdequacy/simulations/convolution/result_surplus.jl @@ -1,16 +1,10 @@ -struct ConvolutionSurplusAccumulator <: ResultAccumulator{Convolution,Surplus} - +struct ConvolutionSurplusAccumulator <: ResultAccumulator{Convolution, Surplus} surplus::Vector{Float64} - end -function merge!( - x::ConvolutionSurplusAccumulator, y::ConvolutionSurplusAccumulator -) - +function merge!(x::ConvolutionSurplusAccumulator, y::ConvolutionSurplusAccumulator) x.surplus .+= y.surplus return - end accumulatortype(::Convolution, ::Surplus) = ConvolutionSurplusAccumulator @@ -18,26 +12,23 @@ accumulatortype(::Convolution, ::Surplus) = ConvolutionSurplusAccumulator accumulator(::SystemModel{N}, ::Convolution, ::Surplus) where {N} = ConvolutionSurplusAccumulator(zeros(N)) -function record!( - acc::ConvolutionSurplusAccumulator, - t::Int, distr::CapacityDistribution -) - +function record!(acc::ConvolutionSurplusAccumulator, t::Int, distr::CapacityDistribution) acc.surplus[t] = surplus(distr) return - end function finalize( acc::ConvolutionSurplusAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} allzeros = zeros(length(acc.surplus)) - return SurplusResult{N,L,T,P}( - nothing, ["__EntireSystem"], system.timestamps, - reshape(acc.surplus, 1, :), allzeros, reshape(allzeros, 1, :) + return SurplusResult{N, L, T, P}( + nothing, + ["__EntireSystem"], + system.timestamps, + reshape(acc.surplus, 1, :), + allzeros, + reshape(allzeros, 1, :), ) - end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl index a261a84..ae3f0f9 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/DispatchProblem.jl @@ -1,5 +1,4 @@ """ - DispatchProblem(sys::SystemModel) Create a min-cost flow problem for the multi-region max power delivery problem @@ -61,17 +60,15 @@ Edges are ordered as: 7. Storage charge from grid (Storage order) 8. Storage charge unused (Storage order) 9. GenerationStorage discharge to grid (GeneratorStorage order) - 10. GenerationStorage discharge unused (GeneratorStorage order) - 11. GenerationStorage inflow to grid (GenerationStorage order) - 12. GenerationStorage total to grid (GeneratorStorage order) - 13. GenerationStorage charge from grid (GeneratorStorage order) - 14. GenerationStorage charge from inflow (GeneratorStorage order) - 15. GenerationStorage charge unused (GeneratorStorage order) - 16. GenerationStorage inflow unused (GeneratorStorage order) - +10. GenerationStorage discharge unused (GeneratorStorage order) +11. GenerationStorage inflow to grid (GenerationStorage order) +12. GenerationStorage total to grid (GeneratorStorage order) +13. GenerationStorage charge from grid (GeneratorStorage order) +14. GenerationStorage charge from inflow (GeneratorStorage order) +15. GenerationStorage charge unused (GeneratorStorage order) +16. GenerationStorage inflow unused (GeneratorStorage order) """ struct DispatchProblem - fp::FlowProblem # Node labels @@ -105,17 +102,15 @@ struct DispatchProblem min_chargecost::Int max_dischargecost::Int - function DispatchProblem( - sys::SystemModel; unlimited::Int=999_999_999) - + function DispatchProblem(sys::SystemModel; unlimited::Int=999_999_999) nregions = length(sys.regions) nifaces = length(sys.interfaces) nstors = length(sys.storages) ngenstors = length(sys.generatorstorages) maxchargetime, maxdischargetime = maxtimetocharge_discharge(sys) - min_chargecost = - maxchargetime - 1 - max_dischargecost = - min_chargecost + maxdischargetime + 1 + min_chargecost = -maxchargetime - 1 + max_dischargecost = -min_chargecost + maxdischargetime + 1 shortagepenalty = 10 * (nifaces + max_dischargecost) stor_regions = assetgrouplist(sys.region_stor_idxs) @@ -154,7 +149,11 @@ struct DispatchProblem limits = fill(unlimited, nedges) injections = zeros(Int, nnodes) - function initedges(idxs::UnitRange{Int}, from::AbstractVector{Int}, to::AbstractVector{Int}) + function initedges( + idxs::UnitRange{Int}, + from::AbstractVector{Int}, + to::AbstractVector{Int}, + ) nodesfrom[idxs] = from nodesto[idxs] = to end @@ -202,76 +201,85 @@ struct DispatchProblem initedges(genstor_inflowunused, genstor_inflow_nodes, slack_node) return new( - FlowProblem(nodesfrom, nodesto, limits, costs, injections), - - region_nodes, stor_discharge_nodes, stor_charge_nodes, - genstor_inflow_nodes, genstor_discharge_nodes, - genstor_togrid_nodes, genstor_charge_nodes, slack_node, - - region_unservedenergy, region_unusedcapacity, - iface_forward, iface_reverse, - stor_dischargeused, stor_dischargeunused, - stor_chargeused, stor_chargeunused, - genstor_dischargegrid, genstor_dischargeunused, genstor_inflowgrid, + region_nodes, + stor_discharge_nodes, + stor_charge_nodes, + genstor_inflow_nodes, + genstor_discharge_nodes, + genstor_togrid_nodes, + genstor_charge_nodes, + slack_node, + region_unservedenergy, + region_unusedcapacity, + iface_forward, + iface_reverse, + stor_dischargeused, + stor_dischargeunused, + stor_chargeused, + stor_chargeunused, + genstor_dischargegrid, + genstor_dischargeunused, + genstor_inflowgrid, genstor_totalgrid, - genstor_gridcharge, genstor_inflowcharge, genstor_chargeunused, - genstor_inflowunused, min_chargecost, max_dischargecost + genstor_gridcharge, + genstor_inflowcharge, + genstor_chargeunused, + genstor_inflowunused, + min_chargecost, + max_dischargecost, ) - end - end -indices_after(lastset::UnitRange{Int}, setsize::Int) = - last(lastset) .+ (1:setsize) +indices_after(lastset::UnitRange{Int}, setsize::Int) = last(lastset) .+ (1:setsize) function update_problem!( - problem::DispatchProblem, state::SystemState, - system::SystemModel{N,L,T,P,E}, t::Int -) where {N,L,T,P,E} - + problem::DispatchProblem, + state::SystemState, + system::SystemModel{N, L, T, P, E}, + t::Int, +) where {N, L, T, P, E} fp = problem.fp slack_node = fp.nodes[problem.slack_node] # Update regional net available injection / withdrawal (from generators) for (r, gen_idxs) in zip(problem.region_nodes, system.region_gen_idxs) - region_node = fp.nodes[r] - region_netgenavailable = available_capacity( - state.gens_available, system.generators, gen_idxs, t - ) - system.regions.load[r, t] + region_netgenavailable = + available_capacity(state.gens_available, system.generators, gen_idxs, t) - + system.regions.load[r, t] updateinjection!(region_node, slack_node, region_netgenavailable) - end # Update bidirectional interface limits (from lines) for (i, line_idxs) in enumerate(system.interface_line_idxs) - interface_forwardedge = fp.edges[problem.interface_forward_edges[i]] interface_backwardedge = fp.edges[problem.interface_reverse_edges[i]] lines_capacity_forward, lines_capacity_backward = available_capacity(state.lines_available, system.lines, line_idxs, t) - interface_capacity_forward = min( - lines_capacity_forward, system.interfaces.limit_forward[i,t]) + interface_capacity_forward = + min(lines_capacity_forward, system.interfaces.limit_forward[i, t]) updateflowlimit!(interface_forwardedge, interface_capacity_forward) - interface_capacity_backward = min( - lines_capacity_backward, system.interfaces.limit_backward[i,t]) + interface_capacity_backward = + min(lines_capacity_backward, system.interfaces.limit_backward[i, t]) updateflowlimit!(interface_backwardedge, interface_capacity_backward) - end # Update Storage charge/discharge limits and priorities - for (i, (charge_node, charge_edge, discharge_node, discharge_edge)) in - enumerate(zip( - problem.storage_charge_nodes, problem.storage_charge_edges, - problem.storage_discharge_nodes, problem.storage_discharge_edges)) - + for (i, (charge_node, charge_edge, discharge_node, discharge_edge)) in enumerate( + zip( + problem.storage_charge_nodes, + problem.storage_charge_edges, + problem.storage_discharge_nodes, + problem.storage_discharge_edges, + ), + ) stor_online = state.stors_available[i] stor_energy = state.stors_energy[i] maxenergy = system.storages.energy_capacity[i, t] @@ -289,10 +297,8 @@ function update_problem!( end discharge_capacity = - min(maxdischarge, floor(Int, energytopower( - energydischargeable, E, L, T, P))) - updateinjection!( - fp.nodes[discharge_node], slack_node, discharge_capacity) + min(maxdischarge, floor(Int, energytopower(energydischargeable, E, L, T, P))) + updateinjection!(fp.nodes[discharge_node], slack_node, discharge_capacity) # Largest time-to-discharge = highest priority (discharge first) dischargecost = problem.max_dischargecost - timetodischarge # Positive cost @@ -305,26 +311,37 @@ function update_problem!( energychargeable = (maxenergy - stor_energy) / chargeefficiency charge_capacity = - min(maxcharge, floor(Int, energytopower( - energychargeable, E, L, T, P))) - updateinjection!( - fp.nodes[charge_node], slack_node, -charge_capacity) + min(maxcharge, floor(Int, energytopower(energychargeable, E, L, T, P))) + updateinjection!(fp.nodes[charge_node], slack_node, -charge_capacity) # Smallest time-to-discharge = highest priority (charge first) chargecost = problem.min_chargecost + timetodischarge # Negative cost updateflowcost!(fp.edges[charge_edge], chargecost) - end # Update GeneratorStorage inflow/charge/discharge limits and priorities - for (i, (charge_node, gridcharge_edge, inflowcharge_edge, - discharge_node, dischargegrid_edge, totalgrid_edge, - inflow_node)) in enumerate(zip( - problem.genstorage_charge_nodes, problem.genstorage_gridcharge_edges, - problem.genstorage_inflowcharge_edges, problem.genstorage_discharge_nodes, - problem.genstorage_dischargegrid_edges, problem.genstorage_totalgrid_edges, - problem.genstorage_inflow_nodes)) - + for ( + i, + ( + charge_node, + gridcharge_edge, + inflowcharge_edge, + discharge_node, + dischargegrid_edge, + totalgrid_edge, + inflow_node, + ), + ) in enumerate( + zip( + problem.genstorage_charge_nodes, + problem.genstorage_gridcharge_edges, + problem.genstorage_inflowcharge_edges, + problem.genstorage_discharge_nodes, + problem.genstorage_dischargegrid_edges, + problem.genstorage_totalgrid_edges, + problem.genstorage_inflow_nodes, + ), + ) stor_online = state.genstors_available[i] stor_energy = state.genstors_energy[i] maxenergy = system.generatorstorages.energy_capacity[i, t] @@ -332,8 +349,7 @@ function update_problem!( # Update inflow and grid injection / withdrawal limits inflow_capacity = stor_online * system.generatorstorages.inflow[i, t] - updateinjection!( - fp.nodes[inflow_node], slack_node, inflow_capacity) + updateinjection!(fp.nodes[inflow_node], slack_node, inflow_capacity) gridinjection_capacity = system.generatorstorages.gridinjection_capacity[i, t] updateflowlimit!(fp.edges[totalgrid_edge], gridinjection_capacity) @@ -354,10 +370,8 @@ function update_problem!( end discharge_capacity = - min(maxdischarge, floor(Int, energytopower( - energydischargeable, E, L, T, P))) - updateinjection!( - fp.nodes[discharge_node], slack_node, discharge_capacity) + min(maxdischarge, floor(Int, energytopower(energydischargeable, E, L, T, P))) + updateinjection!(fp.nodes[discharge_node], slack_node, discharge_capacity) # Largest time-to-discharge = highest priority (discharge first) dischargecost = problem.max_dischargecost - timetodischarge # Positive cost @@ -370,34 +384,30 @@ function update_problem!( energychargeable = (maxenergy - stor_energy) / chargeefficiency charge_capacity = - min(maxcharge, floor(Int, energytopower( - energychargeable, E, L, T, P))) - updateinjection!( - fp.nodes[charge_node], slack_node, -charge_capacity) + min(maxcharge, floor(Int, energytopower(energychargeable, E, L, T, P))) + updateinjection!(fp.nodes[charge_node], slack_node, -charge_capacity) # Smallest time-to-discharge = highest priority (charge first) chargecost = problem.min_chargecost + timetodischarge # Negative cost updateflowcost!(fp.edges[gridcharge_edge], chargecost) updateflowcost!(fp.edges[inflowcharge_edge], chargecost) - end - end function update_state!( - state::SystemState, problem::DispatchProblem, - system::SystemModel{N,L,T,P,E}, t::Int -) where {N,L,T,P,E} - + state::SystemState, + problem::DispatchProblem, + system::SystemModel{N, L, T, P, E}, + t::Int, +) where {N, L, T, P, E} edges = problem.fp.edges p2e = conversionfactor(L, T, P, E) for (i, e) in enumerate(problem.storage_discharge_edges) energy = state.stors_energy[i] - energy_drop = ceil(Int, edges[e].flow * p2e / - system.storages.discharge_efficiency[i, t]) + energy_drop = + ceil(Int, edges[e].flow * p2e / system.storages.discharge_efficiency[i, t]) state.stors_energy[i] = max(0, energy - energy_drop) - end for (i, e) in enumerate(problem.storage_charge_edges) @@ -407,16 +417,18 @@ function update_state!( for (i, e) in enumerate(problem.genstorage_dischargegrid_edges) energy = state.genstors_energy[i] - energy_drop = ceil(Int, edges[e].flow * p2e / - system.generatorstorages.discharge_efficiency[i, t]) + energy_drop = ceil( + Int, + edges[e].flow * p2e / system.generatorstorages.discharge_efficiency[i, t], + ) state.genstors_energy[i] = max(0, energy - energy_drop) end - for (i, (e1, e2)) in enumerate(zip(problem.genstorage_gridcharge_edges, - problem.genstorage_inflowcharge_edges)) + for (i, (e1, e2)) in enumerate( + zip(problem.genstorage_gridcharge_edges, problem.genstorage_inflowcharge_edges), + ) totalcharge = (edges[e1].flow + edges[e2].flow) * p2e state.genstors_energy[i] += ceil(Int, totalcharge * system.generatorstorages.charge_efficiency[i, t]) end - end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl index 95d5853..75ef785 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SequentialMonteCarlo.jl @@ -3,41 +3,39 @@ include("DispatchProblem.jl") include("utils.jl") struct SequentialMonteCarlo <: SimulationSpec - nsamples::Int seed::UInt64 verbose::Bool threaded::Bool function SequentialMonteCarlo(; - samples::Int=10_000, seed::Integer=rand(UInt64), - verbose::Bool=false, threaded::Bool=true + samples::Int=10_000, + seed::Integer=rand(UInt64), + verbose::Bool=false, + threaded::Bool=true, ) samples <= 0 && throw(DomainError("Sample count must be positive")) seed < 0 && throw(DomainError("Random seed must be non-negative")) new(samples, UInt64(seed), verbose, threaded) end - end function assess( system::SystemModel, method::SequentialMonteCarlo, - resultspecs::ResultSpec... + resultspecs::ResultSpec..., ) - threads = nthreads() - sampleseeds = Channel{Int}(2*threads) + sampleseeds = Channel{Int}(2 * threads) results = resultchannel(method, resultspecs, threads) @spawn makeseeds(sampleseeds, method.nsamples) if method.threaded - if (threads == 1) @warn "It looks like you haven't configured JULIA_NUM_THREADS before you started the julia repl. \n If you want to use multi-threading, stop the execution and start your julia repl using : \n julia --project --threads auto" end - + for _ in 1:threads @spawn assess(system, method, sampleseeds, results, resultspecs...) end @@ -46,26 +44,23 @@ function assess( end return finalize(results, system, method.threaded ? threads : 1) - end function makeseeds(sampleseeds::Channel{Int}, nsamples::Int) - for s in 1:nsamples put!(sampleseeds, s) end close(sampleseeds) - end function assess( - system::SystemModel{N}, method::SequentialMonteCarlo, + system::SystemModel{N}, + method::SequentialMonteCarlo, sampleseeds::Channel{Int}, results::Channel{<:Tuple{Vararg{ResultAccumulator{SequentialMonteCarlo}}}}, - resultspecs::ResultSpec... -) where N - + resultspecs::ResultSpec..., +) where {N} dispatchproblem = DispatchProblem(system) systemstate = SystemState(system) recorders = accumulator.(system, method, resultspecs) @@ -76,87 +71,117 @@ function assess( rng = Philox4x((0, 0), 10) for s in sampleseeds - seed!(rng, (method.seed, s)) initialize!(rng, systemstate, system) for t in 1:N - advance!(rng, systemstate, dispatchproblem, system, t) solve!(dispatchproblem, systemstate, system, t) - foreach(recorder -> record!( - recorder, system, systemstate, dispatchproblem, s, t - ), recorders) - + foreach( + recorder -> record!(recorder, system, systemstate, dispatchproblem, s, t), + recorders, + ) end foreach(recorder -> reset!(recorder, s), recorders) - end put!(results, recorders) - end -function initialize!( - rng::AbstractRNG, state::SystemState, system::SystemModel{N} -) where N - - initialize_availability!( - rng, state.gens_available, state.gens_nexttransition, - system.generators, N) - - initialize_availability!( - rng, state.stors_available, state.stors_nexttransition, - system.storages, N) +function initialize!(rng::AbstractRNG, state::SystemState, system::SystemModel{N}) where {N} + initialize_availability!( + rng, + state.gens_available, + state.gens_nexttransition, + system.generators, + N, + ) - initialize_availability!( - rng, state.genstors_available, state.genstors_nexttransition, - system.generatorstorages, N) + initialize_availability!( + rng, + state.stors_available, + state.stors_nexttransition, + system.storages, + N, + ) - initialize_availability!( - rng, state.lines_available, state.lines_nexttransition, - system.lines, N) + initialize_availability!( + rng, + state.genstors_available, + state.genstors_nexttransition, + system.generatorstorages, + N, + ) - fill!(state.stors_energy, 0) - fill!(state.genstors_energy, 0) + initialize_availability!( + rng, + state.lines_available, + state.lines_nexttransition, + system.lines, + N, + ) - return + fill!(state.stors_energy, 0) + fill!(state.genstors_energy, 0) + return end function advance!( rng::AbstractRNG, state::SystemState, dispatchproblem::DispatchProblem, - system::SystemModel{N}, t::Int) where N - + system::SystemModel{N}, + t::Int, +) where {N} update_availability!( - rng, state.gens_available, state.gens_nexttransition, - system.generators, t, N) + rng, + state.gens_available, + state.gens_nexttransition, + system.generators, + t, + N, + ) update_availability!( - rng, state.stors_available, state.stors_nexttransition, - system.storages, t, N) + rng, + state.stors_available, + state.stors_nexttransition, + system.storages, + t, + N, + ) update_availability!( - rng, state.genstors_available, state.genstors_nexttransition, - system.generatorstorages, t, N) + rng, + state.genstors_available, + state.genstors_nexttransition, + system.generatorstorages, + t, + N, + ) update_availability!( - rng, state.lines_available, state.lines_nexttransition, - system.lines, t, N) + rng, + state.lines_available, + state.lines_nexttransition, + system.lines, + t, + N, + ) update_energy!(state.stors_energy, system.storages, t) update_energy!(state.genstors_energy, system.generatorstorages, t) update_problem!(dispatchproblem, state, system, t) - end function solve!( - dispatchproblem::DispatchProblem, state::SystemState, - system::SystemModel, t::Int + dispatchproblem::DispatchProblem, + state::SystemState, + system::SystemModel, + t::Int, ) solveflows!(dispatchproblem.fp) update_state!(state, dispatchproblem, system, t) diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl index a88296c..b427f6d 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/SystemState.jl @@ -1,5 +1,4 @@ struct SystemState - gens_available::Vector{Bool} gens_nexttransition::Vector{Int} @@ -15,10 +14,9 @@ struct SystemState lines_nexttransition::Vector{Int} function SystemState(system::SystemModel) - ngens = length(system.generators) gens_available = Vector{Bool}(undef, ngens) - gens_nexttransition= Vector{Int}(undef, ngens) + gens_nexttransition = Vector{Int}(undef, ngens) nstors = length(system.storages) stors_available = Vector{Bool}(undef, nstors) @@ -35,11 +33,16 @@ struct SystemState lines_nexttransition = Vector{Int}(undef, nlines) return new( - gens_available, gens_nexttransition, - stors_available, stors_nexttransition, stors_energy, - genstors_available, genstors_nexttransition, genstors_energy, - lines_available, lines_nexttransition) - + gens_available, + gens_nexttransition, + stors_available, + stors_nexttransition, + stors_energy, + genstors_available, + genstors_nexttransition, + genstors_energy, + lines_available, + lines_nexttransition, + ) end - end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl index 8c8a6ec..039474d 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_availability.jl @@ -1,219 +1,202 @@ # GeneratorAvailability struct SMCGenAvailabilityAccumulator <: - ResultAccumulator{SequentialMonteCarlo,GeneratorAvailability} - - available::Array{Bool,3} - + ResultAccumulator{SequentialMonteCarlo, GeneratorAvailability} + available::Array{Bool, 3} end -function merge!( - x::SMCGenAvailabilityAccumulator, y::SMCGenAvailabilityAccumulator -) - +function merge!(x::SMCGenAvailabilityAccumulator, y::SMCGenAvailabilityAccumulator) x.available .|= y.available return - end -accumulatortype(::SequentialMonteCarlo, ::GeneratorAvailability) = SMCGenAvailabilityAccumulator +accumulatortype(::SequentialMonteCarlo, ::GeneratorAvailability) = + SMCGenAvailabilityAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorAvailability + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::GeneratorAvailability, ) where {N} - ngens = length(sys.generators) available = zeros(Bool, ngens, N, simspec.nsamples) return SMCGenAvailabilityAccumulator(available) - end function record!( acc::SMCGenAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.available[:, t, sampleid] .= state.gens_available return - end reset!(acc::SMCGenAvailabilityAccumulator, sampleid::Int) = nothing function finalize( acc::SMCGenAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return GeneratorAvailabilityResult{N,L,T}( - system.generators.names, system.timestamps, acc.available) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return GeneratorAvailabilityResult{N, L, T}( + system.generators.names, + system.timestamps, + acc.available, + ) end # StorageAvailability struct SMCStorAvailabilityAccumulator <: - ResultAccumulator{SequentialMonteCarlo,StorageAvailability} - - available::Array{Bool,3} - + ResultAccumulator{SequentialMonteCarlo, StorageAvailability} + available::Array{Bool, 3} end -function merge!( - x::SMCStorAvailabilityAccumulator, y::SMCStorAvailabilityAccumulator -) - +function merge!(x::SMCStorAvailabilityAccumulator, y::SMCStorAvailabilityAccumulator) x.available .|= y.available return - end -accumulatortype(::SequentialMonteCarlo, ::StorageAvailability) = SMCStorAvailabilityAccumulator +accumulatortype(::SequentialMonteCarlo, ::StorageAvailability) = + SMCStorAvailabilityAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::StorageAvailability + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::StorageAvailability, ) where {N} - nstors = length(sys.storages) available = zeros(Bool, nstors, N, simspec.nsamples) return SMCStorAvailabilityAccumulator(available) - end function record!( acc::SMCStorAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.available[:, t, sampleid] .= state.stors_available return - end reset!(acc::SMCStorAvailabilityAccumulator, sampleid::Int) = nothing function finalize( acc::SMCStorAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return StorageAvailabilityResult{N,L,T}( - system.storages.names, system.timestamps, acc.available) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return StorageAvailabilityResult{N, L, T}( + system.storages.names, + system.timestamps, + acc.available, + ) end # GeneratorStorageAvailability struct SMCGenStorAvailabilityAccumulator <: - ResultAccumulator{SequentialMonteCarlo,GeneratorStorageAvailability} - - available::Array{Bool,3} - + ResultAccumulator{SequentialMonteCarlo, GeneratorStorageAvailability} + available::Array{Bool, 3} end -function merge!( - x::SMCGenStorAvailabilityAccumulator, y::SMCGenStorAvailabilityAccumulator -) - +function merge!(x::SMCGenStorAvailabilityAccumulator, y::SMCGenStorAvailabilityAccumulator) x.available .|= y.available return - end -accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageAvailability) = SMCGenStorAvailabilityAccumulator +accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageAvailability) = + SMCGenStorAvailabilityAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorStorageAvailability + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::GeneratorStorageAvailability, ) where {N} - ngenstors = length(sys.generatorstorages) available = zeros(Bool, ngenstors, N, simspec.nsamples) return SMCGenStorAvailabilityAccumulator(available) - end function record!( acc::SMCGenStorAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.available[:, t, sampleid] .= state.genstors_available return - end reset!(acc::SMCGenStorAvailabilityAccumulator, sampleid::Int) = nothing function finalize( acc::SMCGenStorAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return GeneratorStorageAvailabilityResult{N,L,T}( - system.generatorstorages.names, system.timestamps, acc.available) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return GeneratorStorageAvailabilityResult{N, L, T}( + system.generatorstorages.names, + system.timestamps, + acc.available, + ) end # LineAvailability struct SMCLineAvailabilityAccumulator <: - ResultAccumulator{SequentialMonteCarlo,LineAvailability} - - available::Array{Bool,3} - + ResultAccumulator{SequentialMonteCarlo, LineAvailability} + available::Array{Bool, 3} end -function merge!( - x::SMCLineAvailabilityAccumulator, y::SMCLineAvailabilityAccumulator -) - +function merge!(x::SMCLineAvailabilityAccumulator, y::SMCLineAvailabilityAccumulator) x.available .|= y.available return - end accumulatortype(::SequentialMonteCarlo, ::LineAvailability) = SMCLineAvailabilityAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::LineAvailability + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::LineAvailability, ) where {N} - nlines = length(sys.lines) available = zeros(Bool, nlines, N, simspec.nsamples) return SMCLineAvailabilityAccumulator(available) - end function record!( acc::SMCLineAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.available[:, t, sampleid] .= state.lines_available return - end reset!(acc::SMCLineAvailabilityAccumulator, sampleid::Int) = nothing function finalize( acc::SMCLineAvailabilityAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return LineAvailabilityResult{N,L,T}( - system.lines.names, system.timestamps, acc.available) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return LineAvailabilityResult{N, L, T}( + system.lines.names, + system.timestamps, + acc.available, + ) end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl index 5fc3e9b..b152c74 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_energy.jl @@ -1,273 +1,254 @@ # StorageEnergy mutable struct SMCStorageEnergyAccumulator <: - ResultAccumulator{SequentialMonteCarlo,StorageEnergy} + ResultAccumulator{SequentialMonteCarlo, StorageEnergy} # Cross-simulation energy mean/variances energy_period::Vector{MeanVariance} energy_storageperiod::Matrix{MeanVariance} - end -function merge!( - x::SMCStorageEnergyAccumulator, y::SMCStorageEnergyAccumulator -) - +function merge!(x::SMCStorageEnergyAccumulator, y::SMCStorageEnergyAccumulator) foreach(merge!, x.energy_period, y.energy_period) foreach(merge!, x.energy_storageperiod, y.energy_storageperiod) return - end accumulatortype(::SequentialMonteCarlo, ::StorageEnergy) = SMCStorageEnergyAccumulator -function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::StorageEnergy -) where {N} - +function accumulator(sys::SystemModel{N}, ::SequentialMonteCarlo, ::StorageEnergy) where {N} nstorages = length(sys.storages) energy_period = [meanvariance() for _ in 1:N] energy_storageperiod = [meanvariance() for _ in 1:nstorages, _ in 1:N] - return SMCStorageEnergyAccumulator( - energy_period, energy_storageperiod) - + return SMCStorageEnergyAccumulator(energy_period, energy_storageperiod) end function record!( acc::SMCStorageEnergyAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} totalenergy = 0 nstorages = length(system.storages) for s in 1:nstorages - storageenergy = state.stors_energy[s] - fit!(acc.energy_storageperiod[s,t], storageenergy) + fit!(acc.energy_storageperiod[s, t], storageenergy) totalenergy += storageenergy - end fit!(acc.energy_period[t], totalenergy) return - end reset!(acc::SMCStorageEnergyAccumulator, sampleid::Int) = nothing function finalize( acc::SMCStorageEnergyAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} _, period_std = mean_std(acc.energy_period) storageperiod_mean, storageperiod_std = mean_std(acc.energy_storageperiod) nsamples = first(first(acc.energy_period).stats).n - return StorageEnergyResult{N,L,T,E}( - nsamples, system.storages.names, system.timestamps, - storageperiod_mean, period_std, storageperiod_std) - + return StorageEnergyResult{N, L, T, E}( + nsamples, + system.storages.names, + system.timestamps, + storageperiod_mean, + period_std, + storageperiod_std, + ) end # GeneratorStorageEnergy mutable struct SMCGenStorageEnergyAccumulator <: - ResultAccumulator{SequentialMonteCarlo,GeneratorStorageEnergy} + ResultAccumulator{SequentialMonteCarlo, GeneratorStorageEnergy} # Cross-simulation energy mean/variances energy_period::Vector{MeanVariance} energy_genstorperiod::Matrix{MeanVariance} - end -function merge!( - x::SMCGenStorageEnergyAccumulator, y::SMCGenStorageEnergyAccumulator -) - +function merge!(x::SMCGenStorageEnergyAccumulator, y::SMCGenStorageEnergyAccumulator) foreach(merge!, x.energy_period, y.energy_period) foreach(merge!, x.energy_genstorperiod, y.energy_genstorperiod) return - end accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageEnergy) = SMCGenStorageEnergyAccumulator function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::GeneratorStorageEnergy + sys::SystemModel{N}, + ::SequentialMonteCarlo, + ::GeneratorStorageEnergy, ) where {N} - ngenstors = length(sys.generatorstorages) energy_period = [meanvariance() for _ in 1:N] energy_genstorperiod = [meanvariance() for _ in 1:ngenstors, _ in 1:N] - return SMCGenStorageEnergyAccumulator( - energy_period, energy_genstorperiod) - + return SMCGenStorageEnergyAccumulator(energy_period, energy_genstorperiod) end function record!( acc::SMCGenStorageEnergyAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} totalenergy = 0 ngenstors = length(system.generatorstorages) for s in 1:ngenstors - genstorenergy = state.genstors_energy[s] - fit!(acc.energy_genstorperiod[s,t], genstorenergy) + fit!(acc.energy_genstorperiod[s, t], genstorenergy) totalenergy += genstorenergy - end fit!(acc.energy_period[t], totalenergy) return - end reset!(acc::SMCGenStorageEnergyAccumulator, sampleid::Int) = nothing function finalize( acc::SMCGenStorageEnergyAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} _, period_std = mean_std(acc.energy_period) genstorperiod_mean, genstorperiod_std = mean_std(acc.energy_genstorperiod) nsamples = first(first(acc.energy_period).stats).n - return GeneratorStorageEnergyResult{N,L,T,E}( - nsamples, system.generatorstorages.names, system.timestamps, - genstorperiod_mean, period_std, genstorperiod_std) - + return GeneratorStorageEnergyResult{N, L, T, E}( + nsamples, + system.generatorstorages.names, + system.timestamps, + genstorperiod_mean, + period_std, + genstorperiod_std, + ) end # StorageEnergySamples struct SMCStorageEnergySamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,StorageEnergySamples} - - energy::Array{Float64,3} - + ResultAccumulator{SequentialMonteCarlo, StorageEnergySamples} + energy::Array{Float64, 3} end function merge!( - x::SMCStorageEnergySamplesAccumulator, y::SMCStorageEnergySamplesAccumulator + x::SMCStorageEnergySamplesAccumulator, + y::SMCStorageEnergySamplesAccumulator, ) - x.energy .+= y.energy return - end accumulatortype(::SequentialMonteCarlo, ::StorageEnergySamples) = SMCStorageEnergySamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::StorageEnergySamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::StorageEnergySamples, ) where {N} - nstors = length(sys.storages) energy = zeros(Int, nstors, N, simspec.nsamples) return SMCStorageEnergySamplesAccumulator(energy) - end function record!( acc::SMCStorageEnergySamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.energy[:, t, sampleid] .= state.stors_energy return - end reset!(acc::SMCStorageEnergySamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCStorageEnergySamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return StorageEnergySamplesResult{N,L,T,E}( - system.storages.names, system.timestamps, acc.energy) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return StorageEnergySamplesResult{N, L, T, E}( + system.storages.names, + system.timestamps, + acc.energy, + ) end # GeneratorStorageEnergySamples struct SMCGenStorageEnergySamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,GeneratorStorageEnergySamples} - - energy::Array{Float64,3} - + ResultAccumulator{SequentialMonteCarlo, GeneratorStorageEnergySamples} + energy::Array{Float64, 3} end function merge!( x::SMCGenStorageEnergySamplesAccumulator, - y::SMCGenStorageEnergySamplesAccumulator + y::SMCGenStorageEnergySamplesAccumulator, ) - x.energy .+= y.energy return - end accumulatortype(::SequentialMonteCarlo, ::GeneratorStorageEnergySamples) = SMCGenStorageEnergySamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::GeneratorStorageEnergySamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::GeneratorStorageEnergySamples, ) where {N} - ngenstors = length(sys.generatorstorages) energy = zeros(Int, ngenstors, N, simspec.nsamples) return SMCGenStorageEnergySamplesAccumulator(energy) - end function record!( acc::SMCGenStorageEnergySamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} acc.energy[:, t, sampleid] .= state.genstors_energy return - end reset!(acc::SMCGenStorageEnergySamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCGenStorageEnergySamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return GeneratorStorageEnergySamplesResult{N,L,T,E}( - system.generatorstorages.names, system.timestamps, acc.energy) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return GeneratorStorageEnergySamplesResult{N, L, T, E}( + system.generatorstorages.names, + system.timestamps, + acc.energy, + ) end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl index 7e6a7ea..02b2aba 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_flow.jl @@ -1,29 +1,20 @@ # Flow -struct SMCFlowAccumulator <: ResultAccumulator{SequentialMonteCarlo,Flow} - +struct SMCFlowAccumulator <: ResultAccumulator{SequentialMonteCarlo, Flow} flow_interface::Vector{MeanVariance} flow_interfaceperiod::Matrix{MeanVariance} flow_interface_currentsim::Vector{Int} - end -function merge!( - x::SMCFlowAccumulator, y::SMCFlowAccumulator -) - +function merge!(x::SMCFlowAccumulator, y::SMCFlowAccumulator) foreach(merge!, x.flow_interface, y.flow_interface) foreach(merge!, x.flow_interfaceperiod, y.flow_interfaceperiod) - end accumulatortype(::SequentialMonteCarlo, ::Flow) = SMCFlowAccumulator -function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::Flow -) where {N} - +function accumulator(sys::SystemModel{N}, ::SequentialMonteCarlo, ::Flow) where {N} n_interfaces = length(sys.interfaces) flow_interface = [meanvariance() for _ in 1:n_interfaces] flow_interfaceperiod = [meanvariance() for _ in 1:n_interfaces, _ in 1:N] @@ -31,46 +22,43 @@ function accumulator( flow_interface_currentsim = zeros(Int, n_interfaces) return SMCFlowAccumulator( - flow_interface, flow_interfaceperiod, flow_interface_currentsim) - + flow_interface, + flow_interfaceperiod, + flow_interface_currentsim, + ) end function record!( acc::SMCFlowAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} edges = problem.fp.edges - for (i, (f, b)) in enumerate(zip(problem.interface_forward_edges, - problem.interface_reverse_edges)) - + for (i, (f, b)) in + enumerate(zip(problem.interface_forward_edges, problem.interface_reverse_edges)) flow = edges[f].flow - edges[b].flow acc.flow_interface_currentsim[i] += flow - fit!(acc.flow_interfaceperiod[i,t], flow) - + fit!(acc.flow_interfaceperiod[i, t], flow) end - end function reset!(acc::SMCFlowAccumulator, sampleid::Int) - for i in eachindex(acc.flow_interface_currentsim) fit!(acc.flow_interface[i], acc.flow_interface_currentsim[i]) acc.flow_interface_currentsim[i] = 0 end - end function finalize( acc::SMCFlowAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - nsamples = length(system.interfaces) > 0 ? - first(acc.flow_interface[1].stats).n : nothing + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + nsamples = + length(system.interfaces) > 0 ? first(acc.flow_interface[1].stats).n : nothing flow_mean, flow_interfaceperiod_std = mean_std(acc.flow_interfaceperiod) flow_interface_std = last(mean_std(acc.flow_interface)) / N @@ -78,71 +66,68 @@ function finalize( fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) - return FlowResult{N,L,T,P}( - nsamples, Pair.(fromregions, toregions), system.timestamps, - flow_mean, flow_interface_std, flow_interfaceperiod_std) - + return FlowResult{N, L, T, P}( + nsamples, + Pair.(fromregions, toregions), + system.timestamps, + flow_mean, + flow_interface_std, + flow_interfaceperiod_std, + ) end # FlowSamples -struct SMCFlowSamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,FlowSamples} - - flow::Array{Int,3} - +struct SMCFlowSamplesAccumulator <: ResultAccumulator{SequentialMonteCarlo, FlowSamples} + flow::Array{Int, 3} end -function merge!( - x::SMCFlowSamplesAccumulator, y::SMCFlowSamplesAccumulator -) - +function merge!(x::SMCFlowSamplesAccumulator, y::SMCFlowSamplesAccumulator) x.flow .+= y.flow return - end accumulatortype(::SequentialMonteCarlo, ::FlowSamples) = SMCFlowSamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::FlowSamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::FlowSamples, ) where {N} - ninterfaces = length(sys.interfaces) flow = zeros(Int, ninterfaces, N, simspec.nsamples) return SMCFlowSamplesAccumulator(flow) - end function record!( acc::SMCFlowSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - - for (i, (e_f, e_r)) in enumerate(zip(problem.interface_forward_edges, - problem.interface_reverse_edges)) - acc.flow[i, t, sampleid] = problem.fp.edges[e_f].flow - - problem.fp.edges[e_r].flow + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} + for (i, (e_f, e_r)) in + enumerate(zip(problem.interface_forward_edges, problem.interface_reverse_edges)) + acc.flow[i, t, sampleid] = problem.fp.edges[e_f].flow - problem.fp.edges[e_r].flow end return - end reset!(acc::SMCFlowSamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCFlowSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) - return FlowSamplesResult{N,L,T,P}( - Pair.(fromregions, toregions), system.timestamps, acc.flow) - + return FlowSamplesResult{N, L, T, P}( + Pair.(fromregions, toregions), + system.timestamps, + acc.flow, + ) end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl index 0972cc6..95f9b4a 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_shortfall.jl @@ -1,6 +1,6 @@ # Shortfall -mutable struct SMCShortfallAccumulator <: ResultAccumulator{SequentialMonteCarlo,Shortfall} +mutable struct SMCShortfallAccumulator <: ResultAccumulator{SequentialMonteCarlo, Shortfall} # Cross-simulation LOL period count mean/variances periodsdropped_total::MeanVariance @@ -21,13 +21,9 @@ mutable struct SMCShortfallAccumulator <: ResultAccumulator{SequentialMonteCarlo # Running UE totals for current simulation unservedload_total_currentsim::Int unservedload_region_currentsim::Vector{Int} - end -function merge!( - x::SMCShortfallAccumulator, y::SMCShortfallAccumulator -) - +function merge!(x::SMCShortfallAccumulator, y::SMCShortfallAccumulator) merge!(x.periodsdropped_total, y.periodsdropped_total) foreach(merge!, x.periodsdropped_region, y.periodsdropped_region) foreach(merge!, x.periodsdropped_period, y.periodsdropped_period) @@ -39,15 +35,11 @@ function merge!( foreach(merge!, x.unservedload_regionperiod, y.unservedload_regionperiod) return - end accumulatortype(::SequentialMonteCarlo, ::Shortfall) = SMCShortfallAccumulator -function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::Shortfall -) where {N} - +function accumulator(sys::SystemModel{N}, ::SequentialMonteCarlo, ::Shortfall) where {N} nregions = length(sys.regions) periodsdropped_total = meanvariance() @@ -67,45 +59,48 @@ function accumulator( unservedload_region_currentsim = zeros(Int, nregions) return SMCShortfallAccumulator( - periodsdropped_total, periodsdropped_region, - periodsdropped_period, periodsdropped_regionperiod, - periodsdropped_total_currentsim, periodsdropped_region_currentsim, - unservedload_total, unservedload_region, - unservedload_period, unservedload_regionperiod, - unservedload_total_currentsim, unservedload_region_currentsim) - + periodsdropped_total, + periodsdropped_region, + periodsdropped_period, + periodsdropped_regionperiod, + periodsdropped_total_currentsim, + periodsdropped_region_currentsim, + unservedload_total, + unservedload_region, + unservedload_period, + unservedload_regionperiod, + unservedload_total_currentsim, + unservedload_region_currentsim, + ) end function record!( acc::SMCShortfallAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} totalshortfall = 0 isshortfall = false edges = problem.fp.edges for r in problem.region_unserved_edges - regionshortfall = edges[r].flow isregionshortfall = regionshortfall > 0 - fit!(acc.periodsdropped_regionperiod[r,t], isregionshortfall) - fit!(acc.unservedload_regionperiod[r,t], regionshortfall) + fit!(acc.periodsdropped_regionperiod[r, t], isregionshortfall) + fit!(acc.unservedload_regionperiod[r, t], regionshortfall) if isregionshortfall - isshortfall = true totalshortfall += regionshortfall acc.periodsdropped_region_currentsim[r] += 1 acc.unservedload_region_currentsim[r] += regionshortfall - end - end if isshortfall @@ -117,7 +112,6 @@ function record!( fit!(acc.unservedload_period[t], totalshortfall) return - end function reset!(acc::SMCShortfallAccumulator, sampleid::Int) @@ -138,93 +132,94 @@ function reset!(acc::SMCShortfallAccumulator, sampleid::Int) fill!(acc.unservedload_region_currentsim, 0) return - end function finalize( acc::SMCShortfallAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} ep_total_mean, ep_total_std = mean_std(acc.periodsdropped_total) ep_region_mean, ep_region_std = mean_std(acc.periodsdropped_region) ep_period_mean, ep_period_std = mean_std(acc.periodsdropped_period) - ep_regionperiod_mean, ep_regionperiod_std = - mean_std(acc.periodsdropped_regionperiod) + ep_regionperiod_mean, ep_regionperiod_std = mean_std(acc.periodsdropped_regionperiod) _, ue_total_std = mean_std(acc.unservedload_total) _, ue_region_std = mean_std(acc.unservedload_region) _, ue_period_std = mean_std(acc.unservedload_period) - ue_regionperiod_mean, ue_regionperiod_std = - mean_std(acc.unservedload_regionperiod) + ue_regionperiod_mean, ue_regionperiod_std = mean_std(acc.unservedload_regionperiod) nsamples = first(acc.unservedload_total.stats).n - p2e = conversionfactor(L,T,P,E) - - return ShortfallResult{N,L,T,E}( - nsamples, system.regions.names, system.timestamps, - ep_total_mean, ep_total_std, ep_region_mean, ep_region_std, - ep_period_mean, ep_period_std, - ep_regionperiod_mean, ep_regionperiod_std, - p2e*ue_regionperiod_mean, p2e*ue_total_std, - p2e*ue_region_std, p2e*ue_period_std, p2e*ue_regionperiod_std) - + p2e = conversionfactor(L, T, P, E) + + return ShortfallResult{N, L, T, E}( + nsamples, + system.regions.names, + system.timestamps, + ep_total_mean, + ep_total_std, + ep_region_mean, + ep_region_std, + ep_period_mean, + ep_period_std, + ep_regionperiod_mean, + ep_regionperiod_std, + p2e * ue_regionperiod_mean, + p2e * ue_total_std, + p2e * ue_region_std, + p2e * ue_period_std, + p2e * ue_regionperiod_std, + ) end # ShortfallSamples struct SMCShortfallSamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,ShortfallSamples} - - shortfall::Array{Int,3} - + ResultAccumulator{SequentialMonteCarlo, ShortfallSamples} + shortfall::Array{Int, 3} end -function merge!( - x::SMCShortfallSamplesAccumulator, y::SMCShortfallSamplesAccumulator -) - +function merge!(x::SMCShortfallSamplesAccumulator, y::SMCShortfallSamplesAccumulator) x.shortfall .+= y.shortfall return - end accumulatortype(::SequentialMonteCarlo, ::ShortfallSamples) = SMCShortfallSamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::ShortfallSamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::ShortfallSamples, ) where {N} - nregions = length(sys.regions) shortfall = zeros(Int, nregions, N, simspec.nsamples) return SMCShortfallSamplesAccumulator(shortfall) - end function record!( acc::SMCShortfallSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} for (r, e) in enumerate(problem.region_unserved_edges) acc.shortfall[r, t, sampleid] = problem.fp.edges[e].flow end return - end reset!(acc::SMCShortfallSamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCShortfallSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return ShortfallSamplesResult{N,L,T,P,E}( - system.regions.names, system.timestamps, acc.shortfall) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return ShortfallSamplesResult{N, L, T, P, E}( + system.regions.names, + system.timestamps, + acc.shortfall, + ) end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl index 4386e87..5384de2 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_surplus.jl @@ -1,52 +1,42 @@ # Surplus -mutable struct SMCSurplusAccumulator <: ResultAccumulator{SequentialMonteCarlo,Surplus} +mutable struct SMCSurplusAccumulator <: ResultAccumulator{SequentialMonteCarlo, Surplus} # Cross-simulation surplus mean/variances surplus_period::Vector{MeanVariance} surplus_regionperiod::Matrix{MeanVariance} - end -function merge!( - x::SMCSurplusAccumulator, y::SMCSurplusAccumulator -) - +function merge!(x::SMCSurplusAccumulator, y::SMCSurplusAccumulator) foreach(merge!, x.surplus_period, y.surplus_period) foreach(merge!, x.surplus_regionperiod, y.surplus_regionperiod) return - end accumulatortype(::SequentialMonteCarlo, ::Surplus) = SMCSurplusAccumulator -function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::Surplus -) where {N} - +function accumulator(sys::SystemModel{N}, ::SequentialMonteCarlo, ::Surplus) where {N} nregions = length(sys.regions) surplus_period = [meanvariance() for _ in 1:N] surplus_regionperiod = [meanvariance() for _ in 1:nregions, _ in 1:N] - return SMCSurplusAccumulator( - surplus_period, surplus_regionperiod) - + return SMCSurplusAccumulator(surplus_period, surplus_regionperiod) end function record!( acc::SMCSurplusAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} totalsurplus = 0 edges = problem.fp.edges for (r, e_idx) in enumerate(problem.region_unused_edges) - regionsurplus = edges[e_idx].flow for s in system.region_stor_idxs[r] @@ -55,7 +45,6 @@ function record!( end for gs in system.region_genstor_idxs[r] - gse_discharge_idx = problem.genstorage_dischargeunused_edges[gs] gse_inflow_idx = problem.genstorage_inflowunused_edges[gs] @@ -63,80 +52,74 @@ function record!( total_unused = edges[gse_discharge_idx].flow + edges[gse_inflow_idx].flow regionsurplus += min(grid_limit, total_unused) - end - fit!(acc.surplus_regionperiod[r,t], regionsurplus) + fit!(acc.surplus_regionperiod[r, t], regionsurplus) totalsurplus += regionsurplus - end fit!(acc.surplus_period[t], totalsurplus) return - end reset!(acc::SMCSurplusAccumulator, sampleid::Int) = nothing function finalize( acc::SMCSurplusAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} _, period_std = mean_std(acc.surplus_period) regionperiod_mean, regionperiod_std = mean_std(acc.surplus_regionperiod) nsamples = first(first(acc.surplus_period).stats).n - return SurplusResult{N,L,T,P}( - nsamples, system.regions.names, system.timestamps, - regionperiod_mean, period_std, regionperiod_std) - + return SurplusResult{N, L, T, P}( + nsamples, + system.regions.names, + system.timestamps, + regionperiod_mean, + period_std, + regionperiod_std, + ) end # SurplusSamples struct SMCSurplusSamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,SurplusSamples} - - surplus::Array{Int,3} - + ResultAccumulator{SequentialMonteCarlo, SurplusSamples} + surplus::Array{Int, 3} end -function merge!( - x::SMCSurplusSamplesAccumulator, y::SMCSurplusSamplesAccumulator -) - +function merge!(x::SMCSurplusSamplesAccumulator, y::SMCSurplusSamplesAccumulator) x.surplus .+= y.surplus return - end accumulatortype(::SequentialMonteCarlo, ::SurplusSamples) = SMCSurplusSamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::SurplusSamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::SurplusSamples, ) where {N} - nregions = length(sys.regions) surplus = zeros(Int, nregions, N, simspec.nsamples) return SMCSurplusSamplesAccumulator(surplus) - end function record!( acc::SMCSurplusSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} edges = problem.fp.edges for (r, e) in enumerate(problem.region_unused_edges) - regionsurplus = edges[e].flow for s in system.region_stor_idxs[r] @@ -145,7 +128,6 @@ function record!( end for gs in system.region_genstor_idxs[r] - gse_discharge_idx = problem.genstorage_dischargeunused_edges[gs] gse_inflow_idx = problem.genstorage_inflowunused_edges[gs] @@ -153,25 +135,23 @@ function record!( total_unused = edges[gse_discharge_idx].flow + edges[gse_inflow_idx].flow regionsurplus += min(grid_limit, total_unused) - end acc.surplus[r, t, sampleid] = regionsurplus - end return - end reset!(acc::SMCSurplusSamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCSurplusSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - return SurplusSamplesResult{N,L,T,P}( - system.regions.names, system.timestamps, acc.surplus) - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + return SurplusSamplesResult{N, L, T, P}( + system.regions.names, + system.timestamps, + acc.surplus, + ) end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl index 778cd8c..f3de85c 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/result_utilization.jl @@ -1,29 +1,20 @@ # Utilization -struct SMCUtilizationAccumulator <: ResultAccumulator{SequentialMonteCarlo,Utilization} - +struct SMCUtilizationAccumulator <: ResultAccumulator{SequentialMonteCarlo, Utilization} util_interface::Vector{MeanVariance} util_interfaceperiod::Matrix{MeanVariance} util_interface_currentsim::Vector{Float64} - end -function merge!( - x::SMCUtilizationAccumulator, y::SMCUtilizationAccumulator -) - +function merge!(x::SMCUtilizationAccumulator, y::SMCUtilizationAccumulator) foreach(merge!, x.util_interface, y.util_interface) foreach(merge!, x.util_interfaceperiod, y.util_interfaceperiod) - end accumulatortype(::SequentialMonteCarlo, ::Utilization) = SMCUtilizationAccumulator -function accumulator( - sys::SystemModel{N}, ::SequentialMonteCarlo, ::Utilization -) where {N} - +function accumulator(sys::SystemModel{N}, ::SequentialMonteCarlo, ::Utilization) where {N} n_interfaces = length(sys.interfaces) util_interface = [meanvariance() for _ in 1:n_interfaces] util_interfaceperiod = [meanvariance() for _ in 1:n_interfaces, _ in 1:N] @@ -31,46 +22,43 @@ function accumulator( util_interface_currentsim = zeros(Int, n_interfaces) return SMCUtilizationAccumulator( - util_interface, util_interfaceperiod, util_interface_currentsim) - + util_interface, + util_interfaceperiod, + util_interface_currentsim, + ) end function record!( acc::SMCUtilizationAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} edges = problem.fp.edges - for (i, (f, b)) in enumerate(zip(problem.interface_forward_edges, - problem.interface_reverse_edges)) - + for (i, (f, b)) in + enumerate(zip(problem.interface_forward_edges, problem.interface_reverse_edges)) util = utilization(problem.fp.edges[f], problem.fp.edges[b]) acc.util_interface_currentsim[i] += util - fit!(acc.util_interfaceperiod[i,t], util) - + fit!(acc.util_interfaceperiod[i, t], util) end - end function reset!(acc::SMCUtilizationAccumulator, sampleid::Int) - for i in eachindex(acc.util_interface_currentsim) fit!(acc.util_interface[i], acc.util_interface_currentsim[i]) acc.util_interface_currentsim[i] = 0 end - end function finalize( acc::SMCUtilizationAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - - nsamples = length(system.interfaces) > 0 ? - first(acc.util_interface[1].stats).n : nothing + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} + nsamples = + length(system.interfaces) > 0 ? first(acc.util_interface[1].stats).n : nothing util_mean, util_interfaceperiod_std = mean_std(acc.util_interfaceperiod) util_interface_std = last(mean_std(acc.util_interface)) / N @@ -78,80 +66,76 @@ function finalize( fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) - return UtilizationResult{N,L,T}( - nsamples, Pair.(fromregions, toregions), system.timestamps, - util_mean, util_interface_std, util_interfaceperiod_std) - + return UtilizationResult{N, L, T}( + nsamples, + Pair.(fromregions, toregions), + system.timestamps, + util_mean, + util_interface_std, + util_interfaceperiod_std, + ) end # UtilizationSamples struct SMCUtilizationSamplesAccumulator <: - ResultAccumulator{SequentialMonteCarlo,UtilizationSamples} - - utilization::Array{Float64,3} - + ResultAccumulator{SequentialMonteCarlo, UtilizationSamples} + utilization::Array{Float64, 3} end -function merge!( - x::SMCUtilizationSamplesAccumulator, y::SMCUtilizationSamplesAccumulator -) - +function merge!(x::SMCUtilizationSamplesAccumulator, y::SMCUtilizationSamplesAccumulator) x.utilization .+= y.utilization return - end -accumulatortype(::SequentialMonteCarlo, ::UtilizationSamples) = SMCUtilizationSamplesAccumulator +accumulatortype(::SequentialMonteCarlo, ::UtilizationSamples) = + SMCUtilizationSamplesAccumulator function accumulator( - sys::SystemModel{N}, simspec::SequentialMonteCarlo, ::UtilizationSamples + sys::SystemModel{N}, + simspec::SequentialMonteCarlo, + ::UtilizationSamples, ) where {N} - ninterfaces = length(sys.interfaces) utilization = zeros(Float64, ninterfaces, N, simspec.nsamples) return SMCUtilizationSamplesAccumulator(utilization) - end function record!( acc::SMCUtilizationSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, - state::SystemState, problem::DispatchProblem, - sampleid::Int, t::Int -) where {N,L,T,P,E} - - for (i, (e_f, e_r)) in enumerate(zip(problem.interface_forward_edges, - problem.interface_reverse_edges)) - + system::SystemModel{N, L, T, P, E}, + state::SystemState, + problem::DispatchProblem, + sampleid::Int, + t::Int, +) where {N, L, T, P, E} + for (i, (e_f, e_r)) in + enumerate(zip(problem.interface_forward_edges, problem.interface_reverse_edges)) acc.utilization[i, t, sampleid] = utilization(problem.fp.edges[e_f], problem.fp.edges[e_r]) - end return - end reset!(acc::SMCUtilizationSamplesAccumulator, sampleid::Int) = nothing function finalize( acc::SMCUtilizationSamplesAccumulator, - system::SystemModel{N,L,T,P,E}, -) where {N,L,T,P,E} - + system::SystemModel{N, L, T, P, E}, +) where {N, L, T, P, E} fromregions = getindex.(Ref(system.regions.names), system.interfaces.regions_from) toregions = getindex.(Ref(system.regions.names), system.interfaces.regions_to) - return UtilizationSamplesResult{N,L,T}( - Pair.(fromregions, toregions), system.timestamps, acc.utilization) - + return UtilizationSamplesResult{N, L, T}( + Pair.(fromregions, toregions), + system.timestamps, + acc.utilization, + ) end - function utilization(f::MinCostFlows.Edge, b::MinCostFlows.Edge) - flow_forward = f.flow max_forward = f.limit @@ -159,9 +143,9 @@ function utilization(f::MinCostFlows.Edge, b::MinCostFlows.Edge) max_back = b.limit util = if flow_forward > 0 - flow_forward/max_forward + flow_forward / max_forward elseif flow_back > 0 - flow_back/max_back + flow_back / max_back elseif iszero(max_forward) && iszero(max_back) 1.0 else @@ -169,5 +153,4 @@ function utilization(f::MinCostFlows.Edge, b::MinCostFlows.Edge) end return util - end diff --git a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl index 8bf81bd..fd43e01 100644 --- a/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl +++ b/src/PRAS/ResourceAdequacy/simulations/sequentialmontecarlo/utils.jl @@ -1,10 +1,11 @@ function initialize_availability!( rng::AbstractRNG, - availability::Vector{Bool}, nexttransition::Vector{Int}, - devices::AbstractAssets, t_last::Int) - + availability::Vector{Bool}, + nexttransition::Vector{Int}, + devices::AbstractAssets, + t_last::Int, +) for i in 1:length(devices) - λ = devices.λ[i, 1] μ = devices.μ[i, 1] online = rand(rng) < μ / (λ + μ) @@ -12,61 +13,58 @@ function initialize_availability!( availability[i] = online transitionprobs = online ? devices.λ : devices.μ - nexttransition[i] = randtransitiontime( - rng, transitionprobs, i, 1, t_last) - + nexttransition[i] = randtransitiontime(rng, transitionprobs, i, 1, t_last) end return availability - end function update_availability!( rng::AbstractRNG, - availability::Vector{Bool}, nexttransition::Vector{Int}, - devices::AbstractAssets, t_now::Int, t_last::Int) - + availability::Vector{Bool}, + nexttransition::Vector{Int}, + devices::AbstractAssets, + t_now::Int, + t_last::Int, +) for i in 1:length(devices) - if nexttransition[i] == t_now # Unit switches states transitionprobs = (availability[i] ⊻= true) ? devices.λ : devices.μ - nexttransition[i] = randtransitiontime( - rng, transitionprobs, i, t_now, t_last) + nexttransition[i] = randtransitiontime(rng, transitionprobs, i, t_now, t_last) end - end - end function randtransitiontime( - rng::AbstractRNG, p::Matrix{Float64}, - i::Int, t_now::Int, t_last::Int + rng::AbstractRNG, + p::Matrix{Float64}, + i::Int, + t_now::Int, + t_last::Int, ) - - cdf = 0. - p_noprevtransition = 1. + cdf = 0.0 + p_noprevtransition = 1.0 x = rand(rng) t = t_now + 1 while t <= t_last - p_it = p[i,t] + p_it = p[i, t] cdf += p_noprevtransition * p_it x < cdf && return t - p_noprevtransition *= (1. - p_it) + p_noprevtransition *= (1.0 - p_it) t += 1 end return t_last + 1 - end function available_capacity( availability::Vector{Bool}, lines::Lines, - idxs::UnitRange{Int}, t::Int + idxs::UnitRange{Int}, + t::Int, ) - avcap_forward = 0 avcap_backward = 0 @@ -78,15 +76,14 @@ function available_capacity( end return avcap_forward, avcap_backward - end function available_capacity( availability::Vector{Bool}, gens::Generators, - idxs::UnitRange{Int}, t::Int + idxs::UnitRange{Int}, + t::Int, ) - caps = gens.capacity avcap = 0 @@ -95,35 +92,24 @@ function available_capacity( end return avcap - end -function update_energy!( - stors_energy::Vector{Int}, - stors::AbstractAssets, - t::Int -) - +function update_energy!(stors_energy::Vector{Int}, stors::AbstractAssets, t::Int) for i in 1:length(stors_energy) - soc = stors_energy[i] - efficiency = stors.carryover_efficiency[i,t] - maxenergy = stors.energy_capacity[i,t] + efficiency = stors.carryover_efficiency[i, t] + maxenergy = stors.energy_capacity[i, t] # Decay SoC soc = round(Int, soc * efficiency) # Shed SoC above current energy limit stors_energy[i] = min(soc, maxenergy) - end - end function maxtimetocharge_discharge(system::SystemModel) - if length(system.storages) > 0 - if any(iszero, system.storages.charge_capacity) stor_charge_max = length(system.timestamps) + 1 else @@ -141,19 +127,17 @@ function maxtimetocharge_discharge(system::SystemModel) end else - stor_charge_max = 0 stor_discharge_max = 0 - end if length(system.generatorstorages) > 0 - if any(iszero, system.generatorstorages.charge_capacity) genstor_charge_max = length(system.timestamps) + 1 else genstor_charge_durations = - system.generatorstorages.energy_capacity ./ system.generatorstorages.charge_capacity + system.generatorstorages.energy_capacity ./ + system.generatorstorages.charge_capacity genstor_charge_max = ceil(Int, maximum(genstor_charge_durations)) end @@ -161,18 +145,18 @@ function maxtimetocharge_discharge(system::SystemModel) genstor_discharge_max = length(system.timestamps) + 1 else genstor_discharge_durations = - system.generatorstorages.energy_capacity ./ system.generatorstorages.discharge_capacity + system.generatorstorages.energy_capacity ./ + system.generatorstorages.discharge_capacity genstor_discharge_max = ceil(Int, maximum(genstor_discharge_durations)) end else - genstor_charge_max = 0 genstor_discharge_max = 0 - end - return (max(stor_charge_max, genstor_charge_max), - max(stor_discharge_max, genstor_discharge_max)) - + return ( + max(stor_charge_max, genstor_charge_max), + max(stor_discharge_max, genstor_discharge_max), + ) end diff --git a/src/PRAS/ResourceAdequacy/utils.jl b/src/PRAS/ResourceAdequacy/utils.jl index 4fc10a0..c6703bf 100644 --- a/src/PRAS/ResourceAdequacy/utils.jl +++ b/src/PRAS/ResourceAdequacy/utils.jl @@ -6,7 +6,6 @@ function mean_std(x::MeanVariance) end function mean_std(x::AbstractArray{<:MeanVariance}) - means = similar(x, Float64) vars = similar(means) @@ -17,7 +16,6 @@ function mean_std(x::AbstractArray{<:MeanVariance}) end return means, vars - end function findfirstunique_directional(a::AbstractVector{<:Pair}, i::Pair) @@ -31,7 +29,7 @@ function findfirstunique_directional(a::AbstractVector{<:Pair}, i::Pair) return i_idx, reverse end -function findfirstunique(a::AbstractVector{T}, i::T) where T +function findfirstunique(a::AbstractVector{T}, i::T) where {T} i_idx = findfirst(isequal(i), a) i_idx === nothing && throw(BoundsError(a)) return i_idx

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