From 899fc19859a31579fff3caad87889241b7ee20d7 Mon Sep 17 00:00:00 2001 From: blepping Date: Fri, 28 Jun 2024 08:45:28 -0600 Subject: [PATCH] Cleanups, documentation updates --- README.md | 339 ++++++++++++++++++++++++++++++---- assets/basic_sampling.png | Bin 0 -> 49070 bytes assets/group_time_example.png | Bin 0 -> 31539 bytes py/substep_merging.py | 207 ++------------------- py/substep_samplers.py | 46 ++--- py/substep_sampling.py | 54 ++---- 6 files changed, 359 insertions(+), 287 deletions(-) create mode 100644 assets/basic_sampling.png create mode 100644 assets/group_time_example.png diff --git a/README.md b/README.md index 9263f91..3171623 100644 --- a/README.md +++ b/README.md @@ -9,86 +9,347 @@ Current status: In flux, not suitable for general use. *Note*: You will basically always have to tweak settings like `s_noise` to get a good result. If the generation looks smooth/undetailed increase `s_noise` somewhere. If it looks crunchy, super high contrast, etc then try reducing noise. +## Usage + +First, a note on the basic structure: + +![Basic nodes example](assets/basic_sampling.png) + +The sampler node connects to a group node. You can chain group nodes, however only one can match per step. Checking for a match starts at the group furthest from the sampler node. So if you have `Group1 -> Group2 -> Group3 -> Sampler`, the groups will be tried starting from `Group1`. Currently matching groups is only time based. + +You will then connect a substeps node to the group. These can also be chained and like groups, execution starts with the node furthest from the group. I.E.: `Substeps1 -> Substeps2 -> Substeps3 -> Group` will start with `Substeps1`. + +Most of these nodes have a text parameter input (YAML format - JSON is also valid YAML so you can use that instead if you prefer) and a parameter input. The parameter input can be used to specify stuff like custom noise types. + ## Nodes -### ComposableSampler +### `OCS Sampler` -**Possible Parameters** +The main sampler node, with an output suitable for connecting to a `SamplerCustom`. This node has builtin support for Restart sampling, if you are +using Restart don't use the `RestartSampler` node. -* `avgmerge_stretch`(`0.4`): Used for `average` and `sample` merge types. See below. -* `model_call_cache`(unset): Caches the result of model calls. For example, Bogacki is 3 model calls per step. The first one usually depends on the merge strategy: `average` for example shares the first model evaluation between substeps, but subsequent model calls (i.e. Bogacki 2nd and 3rd model evaluations) still occur. When the model call cache is active, it's possible to cache those evalutions and avoid a model call for the remaining substeps. If you set `model_call_cache` to `1` then the result of that second call will be cached and if you're running two Bogacki substeps then the second one will use the cached version. Massively accelerates inference (especially when using the `average` merge strategy) but is likely very unsound and inaccurate. Does not apply to the sampler call for the `sample` merge strategy. -* `model_call_cache_threshold`(`1`): Disables caching model call results with a call index below the threshold value (starting at 0). For example, if set to `2` and using a sampler like Bogacki that calls the model two extra times, the first will never be cached. The default value of `1` disabling caching for the first model call per substep. I generally would not recommend setting it to `0`, especially with `average` or `sample` merge strategies. -* `model_call_cache_max_use`(`1000000`): The number of times cache items can be re-used. The default is effectively no limit. Where would this be useful? Let's say you're using the `average` merge strategy and a multi step sampler that calls the model at least one more time with 50 substeps. If you set the value to `25`, the model cache result will be updated around substep 25 which _may_ produce better results than reusing the result 50 times. +You can connect a chain of `OCS Group` nodes to it and it will choose one per step (based on conditions like time). + +#### Input Parameters + +* `restart_custom_noise`: Value type: `SONAR_CUSTOM_NOISE`. Allows specifying a custom noise type when used with Restart sampling. + +#### Text Parameters + +Show in YAML with default values. + +```yaml +# Noise scale. May not do anything currently. +s_noise: 1.0 + +# ETA (basically ancestralness). May not do anything currently. +eta: 1.0 + +# Reversible ETA (used for reversible samplers). May not do anything currently. +reta: 1.0 + +# Scales the noise added when used with Restart sampling. +restart_s_noise: 1.0 + + +# The noise block allows defining global noise sampling parameters. +noise: + # You can disable this to allow GPU noise generation. I believe it only makes a difference for Brownian. + cpu_noise: true + + # ComfyUI has a bug where if you disable add_noise in the sampler, no seed gets set. If you + # are manually noising a sample and have add_noise turned off then you should enable this if + # you want reproducible generations. + set_seed: false + + # Global scale scale for generated noise + scale: 1.0 + + # Whether the generated noise should be normalized before use. Generally a good idea to leave enabled. + normalize_noise: true + + # Dimensions to normalize over (when normalization is enabled). Negative values mean starting + # from the end (i.e. -1 means the last dimension, -2 means the penultimate dimension). + # Latents generally have these dimensions: batch, channels, height, width + # The default of [-3, -2, -1] normalizes noise over the batch. You can try something like + # [-2, -1] to normalize over the batch and channels. See: https://pytorch.org/docs/stable/generated/torch.std.html + normalize_dims: [-3, -2, -1] + + # When caching, the batch size for chunks of noise to generate in advance. Generating a batch of noise + # can be more efficient than generating on demand when using a high number of substeps (>10) per step. + batch_size: 32 + + # Whether to cache noise. + caching: true + + # Interval (in full steps) to reset the cache. Brownian noise takes time into account so + # if using Brownian you will generally want to reset each step. + cache_reset_interval: 1 + + +# Model calls can be cached. This is very experimental: I don't recommend using it +# unless you know what you're doing. +model_call_cache: + + # The cache size. + size: 0 + + # Threshold for model call caching. For example if you have size=3 and threshold=1 + # then model calls 1 through 3 will be cached, but model call 0 will not be (the first one). + # Additional explanation: Some samplers call the model multiple times per step. For example, + # Bogacki uses three model calls: 0, 1, 2 + threshold: 1 + + # Maximum use count for cache items. + max_use: 1000000 +``` + +Any parameters you don't specify will use the defaults. For example if your text parameter block is: + +```yaml +noise: + cpu_noise: false +``` + +Then the rest of the parameters will use the defaults shown above. + +### `OCS Group` + +Defines a group of substeps. -Since it's kind of confusing even for me, a little more explanation: The model call cache caches results for model call indexes between `model_call_cache_threshold` and `model_call_cache - 1`. If you set `model_call_cache_threshold` to `0` and `model_call_cache` to `1` then only the first model call will be cached. If you set `model_call_cache_threshold` to `1` and `model_call_cache` to `2` then call 0 will not be cached, call 1 will be cached, call 2 will be cached, call 3 will not be cached, and so on. #### Merging When running multiple substeps per step, the results will combined based on the merge strategy. Possible strategies (in order of least weird to most weird): +* `simple`: Doesn't merge anything: only runs a single substep per step. * `divide`: Creates a linear schedule between the current sigma and the next and runs the substeps in sequence. The model is called at least once per substep. -* `normal`: The model is called at least once per substep (and possibly additional times for higher order samplers). The result of each substep is noised and the next substep uses that result. Then all the results are averaged. +* `normal`: The model is called at least once per substep (and possibly additional times for higher order samplers). Each substep shares the first model call result. The results are averaged together. *Note*: Since the first model call is shared and the initial input is the same for each substep, there is no point in running multiple identical substeps. Also note: This merge strategy doesn't work well with non-ancestral samplers (i.e. dpmpp_2m or any sampler with `eta: 0`). + -### ComposableStepSampler +#### Node Parameters -This node has a text input for YAML (or JSON) advanced parameters. +* `merge_method`: One of `simple`, `divide`, `normal` +* `time_mode`(`step`): One of `step`, `step_pct`, `sigma`. Time matching mode. Matching based on steps generally will be simplest. Matches are inclusive and steps start at 0 (so step 0 is the first step). `step_pct` is the percentage of total steps (1.0=100%, 0.5=50%, etc). +* `time_start`(`0`): Match start time. +* `time_end`(`999`): Match end time. -For example, you could enter something like this in the field: +Example: + +![Group time filter example](assets/group_time_example.png) + +The left side group matches steps 0, 1, 2. The right side group matches all steps. This setup will use whatever substeps are connected to the first group for the first three steps and the second group will handle the rest. + + +#### Input Parameters + +Currently unused for groups. + + + + +#### Text Parameters + +Show in YAML with default values. ```yaml -reta: 1.1 -leap: 3 -dyn_deta_mode: "deta" +# Noise scale. May not do anything currently. +s_noise: 1.0 + +# ETA (basically ancestralness). May not do anything currently. +eta: 1.0 + +# Reversible ETA (used for reversible samplers). May not do anything currently. +reta: 1.0 + +# Currently unused. +avgmerge_stretch: 0.4 ``` -**Possible Parameters** +### `OCS Substeps` -#### General +#### Step Methods (Samplers) -* `eta`(`1.0`): Will override `eta` in the node if set. -* `dyn_eta_start`(`unset`) and `dyn_eta_end`(`unset`): No effect unless both values are set. Will interpolate between start and end based on the percentage of sampling. *Note*: This is a factor applied to ETA, not a flat value. -* `s_noise`(`1.0`): Will override `s_noise` in the node if set. -* `solver_type`(`midpoint`): Applies to DPM++ 2m SDE. May be one of `midpoint` or `heun` (`midpoint` is generally recommended). +In alphabetical order. -#### Reversible +* `bogacki`: CFG++ enabled. +* `deis`: May not work work ETA > 0. See parameters: `history_limit` +* `dpmpp_2m_sde`: See parameters: `history_limit` +* `dpmpp_2m`: `eta` and `s_noise` parameters are ignored. See parameters: `history_limit` +* `dpmpp_2s` +* `dpmpp_3m_sde`: See parameters: `history_limit` +* `dpmpp_sde` +* `euler_cycle`: CFG++ enabled. See parameters: `cycle_pct` +* `euler_dancing`: Pretty broken currently, will probably require increased `s_noise` values. See parameters: `deta`, `leap`, `deta_mode` +* `euler`: CFG++ enabled. +* `heunpp`: May not work work ETA > 0. See parameters: `max_order` +* `ipndm_v`: May not work work ETA > 0. See parameters: `history_limit` +* `ipndm`: May not work work ETA > 0. See parameters: `history_limit` +* `res` +* `reversible_bogacki`: CFG++ enabled. +* `reversible_heun`: CFG++ enabled. +* `reversible_heun_1s`: CFG++ enabled. See parameters: `history_limit` +* `rk4`: CFG++ enabled. +* `tde`: Uses the [torchdiffeq](https://github.com/rtqichen/torchdiffeq) ODE backend. See `ode_*` parameters below. CFG++ enabled. +* `tode`: Uses the [torchode]((https://github.com/martenlienen/torchode)) ODE backend. See `ode_*` parameters below. CFG++ enabled. +* `trapezoidal`: CFG++ enabled. +* `trapezoidal_cycle`: CFG++ enabled. See parameters: `cycle_pct` +* `ttm_jvp`: TTM is a weird sampler. If you're using model caching you must make sure the entries TTM uses are populated first (by having it run before any other samplers that call the model multiple times). It may also not work with some other model patches and upscale methods. See parameters: `alternate_phi_2_calc` -* `reta`(`1.0`): Reverse ETA. -* `dyn_reta_start`(`unset`) and `dyn_reta_end`(`unset`): No effect unless both values are set. Will interpolate between start and end based on the percentage of sampling. *Note*: This is a factor applied to RETA, not a flat value. +**ODE Solvers** (`tde`, `tode`): -#### Dancing +You will need to have the relevant Python package installed in your venv to use these. TDE cannot handle batches and +each batch item will be evaluated separately. Using `tode` may be faster for batch sizes over 1. -* `leap`(`2`): Distance to try to leap forward. If you set `leap` to `1` you just get plain old Euler ancestral. -* `deta`(`1.0`): ETA used for dance steps. -* `dyn_deta_start`(`unset`) and `dyn_deta_end`(`unset`): No effect unless both values are set. Will interpolate between start and end based on the percentage of sampling. *Note*: This is a factor applied to DETA, not a flat value. -* `dyn_deta_mode`(`lerp`): May be one of: - * `deta`: Scales `deta` based on the value from `dyn_deta_start/end`. - * `lerp`: Does the dance step according to `deta` and then LERPs the non-dance sample result with the dance sample result based on the scale calculated from `dyn_deta_start/end` (which is `1.0` if they are unset). For example, if the dance scale is `0.5` you will get 50% normal sampling, 50% dancing sampling. - * `lerp_alt`: Similar to `lerp` except it LERPs with the leap result instead of a normal Euler ancestral result. +`ode_solver` types for TDE: adaptive: `dopri8`, `dopri5`, `bosh3`, `fehlberg2`, `adaptive_heun`, fixed step: `euler`, `midpoint`, `rk4`, `explicit_adams`, `implicit_adams` -#### RES +`ode_solver` types for TODE: adaptive only: `dopri5`, `tsit5`, `heun`. I haven't much luck with anything other than `dopri5`. -* `res_simple_phi`(`false`): Uses a faster but possibly less accurate method for calculating phi. What does phi do? I haven't the foggiest! -* `res_c2`(`0.5`): Solver partial step size, the default of `0.5` appears to use the midpoint. Setting it to a lower value might possibly be more accurate but slower? +Note that adaptive solvers may be _very_ slow. Think along the lines of 20-100 model calls per substep (or in other words, the equivalent for running that many `euler` steps). Tolerances only apply to adaptive solvers. -#### TTM JVP +**Cycle Samplers** (`euler_cycle`, `trapezoidal_cycle`) -`alterate_phi_2_calc`(`true`): Supposedly works better than disabled when ETA isn't 0. I didn't notice a difference. +Basically a different approach to ancestral sampling. First a crash course on how sampling works: + +Each step has an expected noise level, with the first step generally being pure noise and the end of the last step aiming to end with no noise remaining. Let's say the image on the current step is called `x`, calling the model with `x` gives us a prediction of what the image looks like with all noise removed (`denoised`), however the model is not capable of just removing all the noise in a single step: its prediction will be imprecise. `x - denoised` leaves us with just the noise (we subtract the prediction which theoretically has no noise from the noisy sample). This is a very simplified, but the idea is basically to add the noise back into `denoised`, but scaled so that it matches the amount of noise expected on the _next_ step. `denoised + noise * expected_noise_at_next_step`. + +When doing ancestral sampling, we actually _overshoot_ expected noise for the next step and add less than that amount back to `denoised`. Then we generate some of our own noise and add it, scaled so that the result matches `expected_noise_at_next_step`. `eta` controls how the scale of the overshoot. + +The difference with cycle is that instead of adding `noise * expected_noise_at_next_step`, we instead first add `noise * (expected_noise_at_next_step * (1.0 - cycle_pct))` and then we generate noise and scale it to `cycle_pct` and add it too. Just for example, suppose `cycle_pct` is `0.2`: we'll add 80% of the expected noise at the next step (`1.0 - 0.2 == 0.8`) and then generate the remaining 20% and add it in to meet the expected amount. I don't recommend setting `cycle_pct` to values over `0.5`, especially if using "weird" noise types. + +#### Node Parameters + +* `substeps`(`1`): Number of substeps. Generally involves a model call per substep, so for example setting this to 4 would approximately quadruple sampling time. +* `step_method`(`euler`): Method used for sampling the substeps. May include a parenthesized number (i.e. `rk4 (3)`) which denotes the number of _extra_ model calls required per sample. At least one is always required. So `euler` requires 1 in total, `rk4` requires 4 in total. RK4 is about 4 times slower than `euler`. + +#### Input Parameters + +* `custom_noise`: Value type: `SONAR_CUSTOM_NOISE`. Allows specifying a custom noise type for samplers that generate noise (most of them). + +#### Text Parameters + +Show in YAML with default values. + +```yaml +# Scale for added noise. +s_noise: 1.0 + +# ETA (basically ancestralness). +eta: 1.0 +# No effect unless both start and end are set. Will scale the eta value based on the +# percentage of sampling. In other words, eta*dyn_eta_start at the beginning, +# eta*dyn_eta_end at the end. +dyn_eta_start: null +dyn_eta_end: null + +# CFG++ scale (see https://cfgpp-diffusion.github.io/) +# Setting this to 1.0 is the equivalent of enabling it. Can also be set +# to a negative value (I don't recommend going lower than -0.5). +cfgpp_scale: 0 + +### Reversible Settings ### + +# Reversible ETA (used for reversible samplers). +reta: 1.0 +# Scale of the reversible correction. Can also be set to a negative value. +reversible_scale: 1.0 +# No effect unless both start and end are set. Will scale the reta value based on the +# percentage of sampling. In other words, reta*dyn_reta_start at the beginning, +# reta*dyn_reta_end at the end. +dyn_reta_start: null +dyn_reta_end: null + +### ODE Sampler Settings ### + +# Solver type. +ode_solver: dopri5 +# Relative tolerance (log 10) +ode_rtol: -1.5 +# Absolute tolerance (log 10) +ode_atol: -3.5 +# Max model calls allowed to compute the solution. If the limit is exceeded, it is an error. +ode_max_nfe: 1000 +# Hack that seems to help results. Set to 0 to disable. +ode_fixup_hack: 0.025 + +## torchdiffeq (tde) specific parameters ## +# Used to split the step into sections. Useful for fixed step methods. +ode_split: 1 + +## torchode (tode) specific parameters ## +# Initial step size (as a percentage). +ode_initial_step: 0.25 + +# Coefficients for the step size PID controller. +# See https://en.wikipedia.org/wiki/Proportional%E2%80%93integral%E2%80%93derivative_controller +# These values seem okay with dopri5. +ode_ctl_pcoeff: 0.3 +ode_ctl_icoeff: 0.9 +ode_ctl_dcoeff: 0.2 + +# Controls whether to compile the solver. May or may not work, +# also may or may not be a speed increase as the compiled solver is +# not cached between substeps. +ode_compile: false + +### Other Sampler Specific Parameters ### + +# Used for some samplers that use history from previous steps. +# List of samplers and default value below: +# dpmpp_2m: 1 +# dpmpp_2m_sde: 1 +# dpmpp_3m_sde: 2 +# reversible_heun_1s: 1 +# ipndm: 3 +# ipndm_v: 3 +# deis: 2 (max 3) +history_limit: 999 # Varies based on sampler. + +# Used for some samplers with variable order. List of samplers and default value below: +# heunpp2: 3 +max_order: 999 # Varies based on sampler. + +# Used for dpmpp_2m. One of midpoint, heun +solver_type: "midpoint" + +# Coefficients mode for DEIS. One of tab or rhoab. +deis_mode: "tab" + +# Used for samplers with cycle in the name. Controls how much noise is cycled per step. +cycle_pct: 0.25 + +# Used for ttm_jvp. Supposed works better when ETA > 0 +alternate_phi_2_calc: true + +# Parameters for dancing samplers: +# Number of steps to leap ahead. +leap: 2 +# ETA for dance steps +deta: 1.0 +# dyn_deta works the same as dyn_eta/reta. See above. +dyn_deta_start: null +dyn_deta_end: null +# One of lerp, lerp_alt, deta +dyn_deta_mode: "lerp" +``` -**Note**: TTM is a weird sampler. If you're using model caching you must make sure the entries TTM uses are populated first (by having before any other samplers that call the model multiple times). It may also not work with some other model patches and upscale methods. ## Credits I can move code around but sampling math and creating samplers is far beyond my ability. I didn't write any of the original samplers: -* Euler, DPMPP SDE, DPMPP 2S, DPM++ 2m, 2m SDE and 3m SDE samplers based on ComfyUI's implementation. +* Euler, Heun++2, DPMPP SDE, DPMPP 2S, DPM++ 2m, 2m SDE and 3m SDE samplers based on ComfyUI's implementation. * Reversible Heun, Reversible Heun 1s, RES, Trapezoidal, Bogacki, Reversible Bogacki, RK4 and Euler Dancing samplers based on implementation from https://github.com/Clybius/ComfyUI-Extra-Samplers * TTM JVP sampler based on implementation written by Katherine Crowson (but yoinked from the Extra-Samplers repo mentioned above). -* IPNDM and IPNDM_V adapted from https://github.com/zju-pi/diff-sampler/blob/main/diff-solvers-main/solvers.py (I used the Comfy version as a reference). +* IPNDM, IPNDM_V and DEIS adapted from https://github.com/zju-pi/diff-sampler/blob/main/diff-solvers-main/solvers.py (I used the Comfy version as a reference). * Normal substep merge strategy based on implementation from https://github.com/Clybius/ComfyUI-Extra-Samplers This repo wouldn't be possible without building on the work of others. Thanks! diff --git a/assets/basic_sampling.png b/assets/basic_sampling.png new file mode 100644 index 0000000000000000000000000000000000000000..25830fbb3db82066045b47292d54b71825e35e9c GIT binary patch literal 49070 zcmbrlbyOT}vpq@-2p&jq3Bf(MLxKhm5Zv9}9fEsscNv`E?(Xg~xVysubDQ`3&b?>- zzH|P#_pSvqvznp%>8g6FcI{mq{8L&K837jo1_lOM?1zvX49uHq7?@X*@UXxUNYdFQ z@b=#Nhl(8x3`+OQ@2fZ(6g(K1&oE*_-+wu49<4aJe>8Y*KOeif@?$}R|8YtXTlSiI zURrp(%6sLK77k?8wvom!JRxrm0?A!{{D7xOOZh`=Pr)Pr^EGixLTMX+yoMu1Q%cew zWW2{#Ee6eGqt?q|NfDx*`_W6DoT)=(`d`K=6YsrAI3b_Zgh*o`vrGdXW=UJEHIlYq zRq_Tax|rp4i4;K6BCG=JaGPqs!WJ5d=`aVYJ9Dq$=r=J^UE}oQ@ne zlu*9peanD%2foSxPr{V{)IqoAVY{l1f+eOv&{TxIu|HZkdYpdn-Dn9znsgvphd^46 zVgNBBG44pTac`=&BBm%(+G<)ivk=bLUhG1;qPPhv;2%}>^FH~b(fyV#@A_yYhbhYA zD;!Czdf_Y()XPXAFS+M)ikylv1N$V^-2xI`s-w<3c6fmCjGa z{_(CU)U)%yx&2*p=(lR9OoC?wBwEl9G0T+cs;6lxEZ0L`4t&>h(2lTj3FgtOo>(%3 zYpI3#*Z-3JKPOB6GK*%=9&JocPM4f$f16<{UYI`(u`A#g!zn$8dk4uOt5py|h!=~=7saG#G)@(&iX>tF5$$o&o%PDinD&1Na-R#$0 zPAn0fKgNvF-29F*3fG^RE9Pjtqy&3D(s{VvoLe5QRIzJ$ow15K5gJTgNJ+N17mcMO zSE*QdH=3ChfqkRn|I-G7J+N-@X77ULHFg$K<@~Ihfh)khdWAqN&76;o0V_XrFp86nl&G8Hc#tez z&R$@;!&7cQbCoQ-^#@3H!VezI6p0n2uv*v#`+*WTeD?K~i7k*DCiCU5fL-YmLMaG6 ze#dToJZV0awi@m}$4Gh_Te!lTLA5TIZg$vKe7>k_`>Q*GaN)SkXnphz1)mG1z0u&% z`2s9+v7eCPdI;a6;~?izqN=h?`sJxLxcw!yj(C7^O>cQ-X*IeG<}^ia%U15Yq`b5j z)23jQAy2BamdX-K%!_hAmDen8H#RpGT3xwicpz^>`Bb_srYtvS@hlC-IeiPNX73e` zudm^>n7!8BF+D1OG*D$)*Se{)-g;n237)8JP3${#*9MzJO|>7@pqL_<#`c8IRyJM< z1YzoIC}1S9IG{_kstQadiMe0&P&}SAf*FC^hB-}H{DuVU3wBHx>Us8s>?ck{EiM9! zQXjek%TSP$2VC~1iXK+amVm2QL9oPr#-0-V>f-x8a;~>WBjqWc+r_A@8q zD|eaH?+zJQJY6L-qIMV)%YO3P$*fNTem&zpf+}qbPoLSH+qKy&7Yc&lY0U&NO{h$k zZJ+3bL`Cgp43rozj-pnNZ~2@VoFvjLg6KMg?`<(&9Pa!-yrM%+nJQMS;2} z7MItn;%Lgq+I(PNvBPizJF+*;p6EVuZgQr&CFb-+pkrWk^_{v8cR^hfnO)O5?v+x< zhWSVJw^S&&ng!r(ide{_=6<4&DYdOWVRKniS~0k)HHg6zzcw9i_JrrH1M6wG`Oqde z1-(&2J%bFiDOp;wz1%%Zp@K^B4=(0lEypK;u_{-l^P*t)^ARl4w4_|u*15^k1g5>z z@AgOFD2jBC-)#F9%1t_SPmn7LdbWsnh*&@6<+~n64)4!FL=Ah7p|J|^#6ne^NkW-umpk(?J9$twZ(X}G`JnMe_ztCUAvS+;t+|2K8L5xp&snqK(86R zwi}evH~H4MpJPDjuT(RJ43ANW#5bsZaLoe2ih^S4`1cG)Pfa`w)uFnkRh!M`9 z&(17pFINZrU~<&#Y3yv-)?=jUxE!u==vZOYMM#)@{)fG_!9P#%P-RgK`TqnC zKx(EwUa3n6&2J2R#eWwG=j+Hp1ZnGg`1Y@fazWebU)R4Qp|x zwQ#M?I_+~s~MZ;`(++$cX2>rUo) z)TV!Ry)$lgh9Vj;!Z-~#cUe()V?^?O7q=B}!9v2IklZS4;}fTE?$`nT3FD*R6VnW78Fn#@-TIkr)yK&6s!@sq|mzV;n zs&t%Dy9E}Hg869K23!j+PiXFzZ8L@j=g~cnhZ9~=$*F_ht#9fNE{c^Op5%m)M+8B0 zcjN3+VGWog9`SA0uIeA3J4+8}N_ z$OPCM%h&q!XZE|44IO=85qY_+>YxY4^GoFeZM4>OyHwxc za@X`YNZqVCS4#JIU{J^a#fnk+synxjGE^A$j)0gsy(_)W^_&~dUa_l%n1`a-Es%*@(P;Y0KCRCYxv|V7Rk61 z%gbl7Vb4(!uSSy33?z20viyC-bad&IssXO5@nM3+`8!4BY~67jB)X08(fxLp$F{h; z?vGI9FWCbg++tkT>z(`7+I=B4Wj}BL$Q~{y|0}d&F^F^3Z#7pG6xqCs6F3rFHTqp6 z$==YPLxa;o8lQ~O-Arhat$O(P3R8T1V(Duf4zG5?Chb0bUnikU( zmQgAM2$SXv2>g=77m2~~o$%v^V!5D>fDjMQX>AU02ws}9&>+YT&+~4q-MXz$mt~h_ zm2Poir(vl)?0W#?)QaN;VBX*eCv?qh**$cvc2x`Yp<&I5r}y}wfx+b51-|Ol7}=hQIJ_^vCyc+eD&Ue=0Tw`` z5Di4BB1`U$Wy6-DJ3J0Y6G%z!R5g|OVzgeTtuBoPxP3aFQP1p6 z^ohf+MI)e(nz85NWvnUGTyVuzC( zM4<@?`Ta;XLjQ!p(7;bDl-RI4&6bcm%?1Qot__C3-Q>P~H+eqGeF00Frq$1DeUKw% zny9TR_f_v-$%#(_K`|Sh!V?pMgBvmVHED14>nqT*Rih6iNIf>&)iL3R_6*O< zcI}r2jj7f}X*nLBhZ6AoB{D)L5VEzU879Z5sd2y`7}C3!G2@7hIm9ZqXM(u$JkM+0 zt>uip)(m{<$c5|}lZFSs0Qje0+qluvcxuKznpRep6qGxy#@DVr9+Q|D)T5hUU!Yu3 zqr=EJvFtc?y=TuA53LR$5xxAHBzbi(5l5w@Ihd5fb+$bRcG=9y$*w=nKV(b_d%T-6 zMcE}JqaG9h^R?6)4sN?cyJQ}#xe&c4NXB-WD@g8b_ivB5t>KGj#LXpe?9y;}yf3p#c5fmJ;$8*~+ix3);-Mu$>?W8W2o@6)l_jYwU2Sa6lewxfLz7xt+|Hj+X&$+%2-WJKor$ttI84qkZdJE> z<ac5mqD#y&&TqsJ0LD-5 z&(}`V)6>?Q*Gf|j@}gWB3qCr6uougr_MQXM zq(Pe*ULM{u{LtiQ54S1e9D+}u;z|ZoW#R`n5r}aqs2C^8nTuop{P7+!%_%GMOu-V* zC5O_dTGQLuR1CXpBNr7FwQM(tMgYBKw~L-AIu@RUfkNDv<_jMcWG@X8RGFsK*&nYR z*%KgI2dY`mL8y4PC{`TWQzdo3q8wFvurLEuCv}8@ zzTGsXsx9#*b5iT++*a$mX-x}l(9dvowiT*)gcnXs5bAJT8%&AT#{gj>`YfxAbalsb z|BoLrE3Ba3qodJ*xay&Ouzufk^C+%vj-;gS_yJ>#KT?Jd5^@h!>mGJH(ca82U9F>v z@pAgGXWx8xpf)`{%jB%hpRdIpho$M_TUlwVPLCxGim~ep+sct?BRy5-dxBi=Ooq~D z{;l`Zs=8%&RwtGw)963{{JdyrKY4{iSc5BXWiQEsnZXMCTTD{?Gc@r5#R4!I66~8d z57&m<2Q{8)Dv`(hr}~gF?x(@$`#HEf=K-ZK0@l>Z3tP-)$SWWdNb-2$r*S)U>oUs! z{MmoYU#1U!_VsSu%32gkM~jk_Xu>F)|CUXQDT&E!7=shoK0h>b@sGt!zdx=Rh?)yj7z<`W#;sj3U z^1KI$n#Q*evgmb&#?bmePBKa;K4z(b&3s{g zVCNEWy+06~jK<%zfW6m?*YvcjfzPq!Y1U-fWq4a-e>zyc0AVFk3fjrfKfbIsGS#g) zD^-%XkQw=b36nG72e5gs-}uzAjS z2oCn2uU8%%8Y(O<&Coadkt?0Wk>ugevBFxr!U^;OdO$DWKx)Kq!OXR8%Q>+>?eMFV zt+=QT1x67$+`yrxNe`EZ2+Q7B&E1_xVdjMRZ+h0>_vZ&~S&DM1y-Hx(H=pV0?0zZ6Zu8Pgi@S-$+W8V76Y9*IAY?Aapa9v6(NF^4guyEO+iW;*PljC+CCQ`Z<@(2l>@u2Q z{}q9sHtgr-9pO4zwv=hq(mpLeW&SZ`HQc{I4Ed{C3gog??&{$LX;6+w6LWJ~$z-K1 zkjnS$4Fg4x>k3Lrbi4BD@JEI=QR}2Bax~O#hRO`YgHN8$BxGfLwyph z7kngahKoXiW<}rDOb7*7>K6jGVbSAVj0LaH-g>KN~M^FvBZQAlu(KJ9Mvm>qqkeMw(tGt058oB`}X zfC48C!iYH+S|vWd!~3N*XeVVEC#0gnxt5L>pNJ;oBK$6e%}Q?~P~vU}Ld0n{uifUs zgAnP3Tj=15D-9YtjkLuMyQminejm{R|pWgl2sm zKNVZ>+^C#HsVsp^jWqYN+X2l7!gt#}KyCDW6`cEaSBFUS6lw z&UYB2d1?vL#8?NHd5&NjAe+Z2DDXfhy<8r^3{h?@k%wgs=q;-&^qlx8B9T0yr=EAg zM(JMuKzh$tx1l27uHK!2j&1@RU#3=u=GES6j~eK-I+#eQWM_X@(@c|{l?2G2K&tr!m%66Px{;HJt`#C3Ilv-dhB_pyT+_$#W=!ZY*e&cl&!*d42A zXlM`@3u_iEK4N_`A+&vcc6>WjSWvKalTvPU*6#VT<;sq6!nloClr$Yb@Rts5tYvkr z-Wd!j+0wTCQL}1}ST{mm4`bW6?>FxAv(amKP98W~Xo^f;RMpkZZn&()YtVjds5Wzh z4Gw-^Z5k&uMz~Uc5F){8dxafn7x|Dn@ZR*+p+WuQr%%kr+Wgr$*~W3P{SA7evk=~^ z)49N~o8zz8NJzNj3DdFqj*pdy-T;`f-L+t!B<^bAWn&Atu^7v&ukUVZ8!;pyBTJf} z#}*eKns3=vBG>pDQ9b?f%9Q{pRa;}X&pwV8OU}2i_P}*@ka}0%H;`LmI#%H+8-KLL z>0fgN$uf$H2hy~Kp9%-~K~p_DrQ955d!JRw$f()%*iwENuN@ofL^X|wNpMFYP4C<1 z=99W%IGe@KFq&3d%FGVaA83D&KTrgxN=*= z4&LdKY0b>fhb^Az%^z6`3JoV40Fg9oCTMICa*9hy(X|~d3d+fS0lU|w9vtAJY;Vc^ zQWr3_eY#m-w#cq6i*UeWlUM#FId-BEr?bkc(5m{t3&ax#KFX}svcPv8Mqk*g>)w0m z%YN?oQ+Z#s5sEJX_-?Urak5HkOSv>FGt;vd4{BD-uH6e^gf^I^5ncj2#;c5&9#=R` zj;Gh5b*dK4oKOvsaO_?cL0Fr0Kf8(rb0FL8KB4j(%vs(dB+ksRx;I>Li-dE8nw7Uk z&nFt=qfi(aY##w7H_42B8V}(p%K$vq`Vc=v-}ndav?&EhPx0;*v7<(g-^%B*ruN4V zuS=900^aY2+n^E^mgo*(f&aL`rw=4(3Fr#&I5;TY5b<;eW_YgiW?bXd zS$Evo?X8wFGc-SH@u^;rVQFxrFIlz{Rt*T**u1AvGIBY*>Q`+WIIYj{Z2k3*U*qEA zCdA886KCL-Lko-_^-=3%ya<>UZ6G6aRqorkK!0h8~FI*_RWKCcx zt4#<6(r`G(ON^%7Dge#^Jd(XUQkd;vuGQeoAb>UaBH4+ z>tck4r`+Fu#gb`Xpe+YCuejaXZ1u}NTptUonj#R1HIe%nqKK{;<$l9=ysiKWSf}7f ztC3^B_EF+`wX{s1KG%7H<&{`tTx_bcTf1SEth|~;xJ>7iY0W$JA3u+)-_w~D-AP}f zZTt!)H&99+FP(!1H#n+&r+?S>1h#pUcAGS!XIn#YW@To8mM@D zy{h{6&+81hrk?|XT3P5W0`S+s2^lLG2RB^tQH;iA@qMbVuH}KWp6Iyp5pYQ-B$U6$ zv?eM&eh^5{8+BGKh0GmBKPd}R*s=_y;sO@6i96{wxT=9B0asC0^ZUCK1-BG&V4>~2 zqz|AOmDMprzl(B}F`CeVlA;aYNIrQ?hzX_3-oJ`(d1GV9{GGC7?}OC`4+TY2vt4)4 z&l2$89>{wE)Ul5tW37*{9E|=OM>@U(s&y0GpE`2P5~S6?KI8ASJhg)He&z+_|Mc5v zvRbOO0D5d%s7d(k5Frp#_W>EP-=@eN;jpQXn)1anyS>q(NOgC{5dfY}AP5|BQF-x) z0n^OP>~~o?y10ZUe-AT7+f)+4*S+hjqls{zHxDo;#Df$x(+?D_fH4%x3%_(1l3N)I z=R7_IFTC&o04XqYU}`onHblZmHDJZ67uY3cU?7~sRfU!$PdRR;*$?01JVxe3ro+3;5xW!0!-y6pZfEJ5Zt4pYrga6=&5}0Njs-ggSySUVvZ#*_^ zh=I~n%ULDR(nkbAByzt}$=N|b{D9JP-@rjYv184izw&C_jj%mA1k}0)KEn_Ql9!QM z+6|V)C>E|i0H_{qBv>a=d8wwHyzoi%CA8uh@-!7<&z$ONvO(pRMa{pe=@05sR%9+Te1!fxLM+-w!*GXm<4`LoHbI=3|*8eWW3IqC^D!kgu z2lxWni0mpq+T}v!VPrNZ&@BaKFg@5 z%>+zQb*TY2ELuLLQ<11pXEbiT1h=>(<{c7(@FEw$bNhaeT-cJ{F)_)h?v77L(Btt$ z0`%1%DzdFkTta$FX~3Ay#Qrs`!lvLfUx5#|BH<)(I`Q%;+1QL?T9hAVwP@3IF`~9N z7#XqD7I|o2j?8CO(b3TrYGg87j$>{l;jbkf0(&%M>$pY4E|kAJzY`X|uy7agl0 z5_cDB&z;?e{O?Yq@dE(l`d_`$;+}nbN|}#G-6t&;TulgXgqk`D4dv&o)9LmYhb7J5I}G_Un=(j9CkigTyA^JI=5!s zpMwAD4J^u52u*pW-R>v{0X+&KPrp$Hoz7+evZsv);dGkTyL%YRpPK=DhfrD|_|;rNMnO5GKQ8x7hHqYLjwsU>!emc`L7^ zCT!sHeud#+z<@|IjCjzyW^!;)RH<^k2bmP;6fb(jT(3`iruXHIr^>?XO2BKLFtiX; z95c`5EjmD0wYKIW_@xx9Tcu*db%Y&8J{(V}yAd6mB>;b(VlB>9O~7rx@o0l}ABThF z8h}D5{p%Nt%Aw-DMd({p{tNiaol!Cd2APIJVdMQ>A`}wQh^+|jQ~gyn06!0atU2(J z2)JVTS3TGf!5#^xZ4eZ1V!^<#dcBf642feUp!815x`_rmrLqjiH}qKUwcRUXk6lEk zx%v44kmpAu(;~CK%GvdgAwxKfwjVRRYP)a8zq1Mx5LRU*^~8^;jqhLCpH75}61jy5 z!l72UR5eY_j8_=)KULS2xt+8m6dh3SwBE|x($uk81|0gM3N13&O$Bw_Dma5EL0C!PF&9- zv5|b*Dmb3A&%1jmE>?{AsoB%2vm%i`>j|i-I!I(&n|*NOUmhF1cZ<`J5{dQ_pqh;K zf_Zwl-5jK$m}-!~0+=FUVPSLSx^z^2RY@rat4pKs~89gogt^L8F^ zV}APOOKmM!C{l|f{xAlIOfZW~J*U=wv|!MELOi5ekpHHxj=;4tFh+hjPUVY|#{Jsb z82laOcuZCZNKRWEWCV-AUXaCfxjyFg_JG_*YgtP+?8gr7{mG&=l~sMXXJ^fs=nrRK z8HPJ;8@t#ZYS~UoN=h6iw`@6PQ!G^%(@2X;v22YalZgL&)O6Zn<92hjV-?A}^MsSB zbhPUpg~XS1 zOqxF`@sa!RsHy>y-ju}e#3wVB>_1|d;~@gu)^?-n>2+M=IlvCiO`b5`YPQ*QUdw_@ zx(6izJycOEA6;iu|C@p$%B+(TPBu5ig3l>l9H|RXD1RxWH z482pBQ5beJqX+Dn4{!-Q{6;8BGD#cZUWPa3e9wC%m6esv2AkwzyU`N#WL(tAB{fOI z8QiD|p_$jCcb6GrVq)9tqJ-;D{)kkx)VdE>``tY~I#o+57yF&PXy-P{UvI;vIgNlqS zFI@47MQU-!1S<9q321!;w<~3|mgou6N&O3YaGN}aQNYXtp+17frt#U`DRcG6bpEq0r2?L;q|ifrIh>QMBn3CS1{Y-n$MeI*9)y;C zMiMVX#qs$Oab{-b`=N))D85J-c89zSpO~=lJBHRrCaBA`0$YiejO*bn&-K+5K9}2Ts*lq)^P^x)sF4QjlNJwfWq}<2|+it(-k`?$G75<+gup?AFq% zNRRhwyz6>roZj6k>((MHP#Q$i;=q;gbmF9MkpAN<>kbbREXM5M!|mwY&Ha+e6pi)n zAW#*5{q*ZFZZ~Gp{fZ9-O*}Pm;hYECbW`+Fh59aLc(51;vH>~PAS%OAZ|Uvvcz}3% z+Q|U_g#8!B`?(4|QMqXOJK}cELIaj08!nBaa;ufan!%A|7BRrRWLX+t^6T3XSIHbD zbGsS{GHH{GNKUdwT1Ss;$)8{~z6ra$`?MYRD_%hkXjlw{-)-l8l1yS#XprEQ2WgEQ zwT&oZnoZisxh+PR3d+^JMX1B9f`$ryw4_lCc>lqsTJlr)SuY^6r#*>YkkX-R9&9Tf4TK@hCX;`&_pz^>p9w8yN9 zzXjh^wiMLWB>{?CZ;Uq~{BW+yrYpeJ&KbAz>ag6VK|MAhuFB++9LN+y>|k021uL-U zQvoG|QP;yY%oY)MZ!hv84xjGZK$Nt8RZr-OQ@uL<;NakV{eVZ<@bIumh8M7#DH&+= z4l!@NN`!la&FAZbI|KtNJ(e7;)H65B)api?H0n8zZpLxUTL?iz!CmX^nU%gVDJes5 zZox9UqiOqdZTx}(C1H&2Y8F>RfoPB9LLhsH*hCc zim^%;2h4Ur-wZj9T+MWHvPFiy65$2t-(~l)>%nnv+Z%$N-Qy;iBdc+}uY15$#U8S2 zn21x7<|&_uLmmWK>T_wMzvdQMq1x}t{^E)OW-U6#dx~U5pmUX*nq2NHGQLw52Y|g~ zDob$vymGDOYG-=~Pyn^`SPj0&fTptQ{GK5NN7^_x13pT;(&lmf^Ot?pp{)DMEf^%D zI71yCKD*PfZa0_MtY+9PmPb2J4J(`$*w$87v-}PIr3{1O=U*xd)2IP18=Kb9qx{&MNlG%uX%ZSt6t?L1)o{zG#pyQg2i(4K<5|5&~uuxLG{gB zJC%iCod|`v6TNSnWBiPa!A!!Kb(Ptvu^*vr#=ZnfcSB=i6vT`^^YhApjQCi)f9*Os zH95fT8rIqQdKeQC0AbgaRvkx6b&&w#e!;>?_7kLKEzhd0_d9s%WoupoH1CSLEbH`8 z{@PjrsI$gF(V#-<`*&gqK8;R`I`GNyxa(W)`1niYo;p2(koe25xKcuW90HKzO(PMz<#8dE;?#rG3N0=xwfk6Xr7K0W zC`F^L8>QiL>$P7d1K)Zj(l6samWt@b7`3YEUdXVN{*ZiLICi{pg;Hd`ILdrN+yjf3PySWZRLgZ3|Pj zLr7<*YYjn^m~Zrio2Z!R?(IRt!xFSNXTg+sYLgd8a@=L*I6^6+E-ox9%4#f1E*dli ztf+GDfl1awkzV2M(3W4NWi&hYR}|J(f1443&CIIG-2B<;;lI>;6h-r(V!F?6g-^Wa14CVrkJR$MF_;!66~}R;RB#0cqH_U;U6U0(0=j zVrik(f?FiV=l!l$`_nCdyG7mV@2PFiq_U~~7Ss-#^J}7So0}U{)Q;@Q6*lL;@W(D- zi|3TYOx}w|?$|&xphrq&u>j3=hMjrBA)c2*8FL2x5W9>dN96n0CBW2TbJ*3=M5&hcfIOze9Z7n4WL2qk#2&4>ZUtn$TB* z$Y3s8J3G$H;fTk_%V6TqrO|3p$_t zDH3x-jnT^_NqQ*}70{HYt0xbrh=ZY^%C#P541Go>?Tvh*R!JfA(w`QhBh-bgl{%ql zuP@C&HA?V0!p4;NNHsvU+IFhxu7kqRcJ~Fw3VKQawrJ13unJp>R4S_> z{H_#It2QXQ!}v2XRk|N3l+$*J{S;|6tED!yvR@`)z$gHqRM{=@l{8(**qYL=4`(N8 z)Yv^$TT?&LDE>)LA8pfe_HlyVqReT!5!|l2p;|1aez0GO3dq;!kA?pbv{?9BZwzNB znYDOeU?8iyI`-8YxJnyesF4`E#d7}^m3%XSYR*Kv_p3K9Uh4v*yjH1NCDFDBg7wb% zhHv%imcD`XjuP7u?GLV9U9WL}*ob{_2to0XXD-qRpJJX?ws3csGwrwfW>~7$)B5Bl zCMDKq{zA*6U5u3U-Ca_Q=h8X0?2MGG-c~HvRZFGP= zqj7h=(1L>4Uai5dLvu1PchbW2sgN)w1N?n;5yLL~&HH#B?z9-MY!hMK3kG)fgym&* zdZ6yzu09d1Sxyl|V1S2Fc3PakdZVEXlWksJwH8bH4-f4g%e~|uXMSFC2Zc*)jH3oR zLrUuQ?L3G8rUV$`Own4AeDI$A^@#4CD{Udg>hIzs>cEl4TEtyl&U?$HupQS;-u)p1 zO~ze-$L4)SH$}I+hKkoondqXoK7jkGpF6ctM(h zj^I|0#4vIuCZ>KM%C*{_^`Xg9Bj+v^K5tVxGXoZ{r8A#_@~SRP(Tmm<{0adfq7j_8 z_d3#VV2Bs{s}D$FuL{2E@weW0C1wx904R~?p1Q2<+4YKx z7Y^lQH!eZ*VyMJwrPAMv_nDzAnaQ7qLMwPed(Bvr5WpfELkz7jYiH|S%`esYrfKMI zQ^N_EPAw=X(0*!kaIbf+s4M$9Jzb&OgK!1=hJDo@!zgtkU@%0SiMdMoZq+Shag70$ z$Iob9Ma6~FtZMe+*$wfPL!TVYPm=f6b7{z^fhHlqR2<#(cEeca&Cfhtv#E!%qdAV< z-*$=4_x_}0O`?(jF!fx$U?v*Y3L8*wlXtFETuvES-xf7tzv=!$4T;A${mYC;?c&Hq z0Tr4G>E0r0$18^dTizwHvQjP{dPh=IQ)7QLA2lGK|MQR5HUo2Qz&*LNO@Ft}y6d7FYsJcMpn zvTYf0txr2C-UNLC5g3D`X>Dg`f<6h;xA2bY+xLidX>E_47;TU8D(YjvY=+B*R@UZh zsfODmjZRVFW*?E~8u0rQ6VhPvU~eGHYZ|fr;ixSmAYy9VaomwGO1r0yM)~|00bPwO zdY;-xkS{c+dc^nvh3?x;AKdRULww1Ct%d#6M+_+jfH_-xhMb*yJ^B`xC3k*O(hTm= zCFbYPC>fU2^xW@pMU7}}y?eCll}T*ROVH>AFi*+DLpA9~L6Z=$&jMO#4vb`C;qrcF zbc~m>dh?oZX2$XPowg4Y7fBUg)00I%kj+Z!j8p>{<%#=5L0Fpj|h$rSMf!e=Yfs@o&I^WUh_2YA(H(28Kk-CE)XkehvIxkm<}{w<_~ zD80D2I4C&$nnpsZw5_w{@GfOBV3t6Z`&b}fC@A1g`V%n1sn_1_Gu(Vjc;SIgA48wq zomioF=wOUWIFH(X_a38vHGzQX!(3{tJhMP>uvO1QPM}J&Ga-pcszeIgF%>=i)@}xS zmF0@~!!=QFl%8l@6D#NbxQKUH7}7I~U4G^KA;4U<(D;V{4+>YH`G}!Q2ld;0g`kZ+ zKdErp4`vGPM!?`NI{guZyz$BxEsh*}3R#EZ3iKf^egHE@Y-r>iX;fz%L(en#@~Vw) z37MV~zxPEDa5|rT-VMhSEg0ixt3LUm_kv@Bz-+AY?_N-^&l|`SR~3wkipug=3oZcC ze8hr`>5Zw!48$o(@2qSdz7qQVO`iGp1TgnZmM5pI-Ve%Xl~7Q~bDL8SQE>yc`VPJ>^&=xhxLQ`x_8tyQ4iq8)mFyQl@yC9G%P5~wR$UVN1L%bl zJb>myJ@mTVcKKIw6|bAlC_d(J#@NnCN?eMxs;eq4L(2noTib(a>S&CXj{^J$WfL9E zm=arj_vT))GoI=9#6qM@xKe}JnVmD~{>7UA=zK5pi@je{MtGjfDfU)d;9xu+uE;pa zl8!t&c30TmC7}}wT~5BpdIvQ}1py#Fpt-0Jh9~|Km|Q!CkwdN+YCQu8M;$`KeJ}_A z(hui*D^*L~p(}OE9%H=CHxFJ7`|&9+$t*VE-7`-NTJ|;|69VJyOk4F9A{5lr)X5g} z!Ds@;S#$f8gJTMqaMJ*TQsjtQ{g2+oeu%~kC`Jh*suBVM*+n<+tLr=_)87+U%b{>u zN;bXG!3E^Ce~VpyYQO{Prf#!R!2rPxZOQIKmOM&K&;L`XKv#J>Gz+XRrOMaHb2}DesfhdGpK+k z&H-qgAMiHG^^cQN-2o$sPVji>U%|8*yzU_&oK zJS@CZ0w7hJigVq+>x=DyskWR-_Tq=~ShcVwNYFR<)z5PpAOF+V&;fJ9 z$y_lZ(Z0Xh9qx+ds(|*l8?Zlx&1O$YkM&DIiSe|w;b@_1$?du0>R=_sWGepy28Qp{ zHZTp)x?Wt~`dUEi5}=v>0B7%tT2g?mPN`0(D)(%Uoo`nB3efIwE4etu)yf|N&O~j^V#Di&~c); zULAFSq30ZGY!>;=+4#jH0R#G9SjobhP8&m$lav3PqXZJf3<&AU(HK6PzycicP6YpQ zN4EdzCCKe`d--xy?_j#HM6)L3`3b_P-;ZWEn&`7)Y1BWS6^6@O*@0rAu8xlih=>e4 zP#(29b7C@1e~=Ns)aW{Xt<@6YMY2{hbKnOOk+bO-nZZAL#J~QvW2@b_)DT&(4XaNJ zXfLM9EFgaf7B73l0imkA+pw<6bA_wX@vv8BD4|NXC&YW8h0S6VK3Umpsg`bREU9Zo zKHvH9zeyGXZ+`wV!(_kGJ)4}$Tt7$KTn6{%CxeNcbmZ(F)=Z( zDCz0R85yH0cGD#QjuemGTzhrdWtHpq{#-fHwt<29O65E6?2RvM=F8n{#DY&7zcqj{ z0d7`{3VBxR~_%?2_fK|E|{B7!XTZe`Lned94Yp-oy>? z299*RLFMa*oHoTc$nZSNl%=|p0n(rRG=3t}`Aq`kRPSz~ixYBG_39Db^LEvaorqp@ zxL|_hQ_b|Q*xfts@}GS#3II$xpjzw?hk%<4_OLV89pR?yWHad;r_by-yq1Np_GdC2 zEts*#t-b=YtZ}cNU}*&X5t#A>Ql?uG7b-g(O@PcUn=<_FUqE@Yd5kvkDnLkdh_m@N!bW4dl(5<4+FgB)( zN^SV-Sf)?BAJ`D4`v7-`YVy8;dU2Zf!%xZ?Jbf(H7x(8#E3lBr^fXrvz-QMVstp$s z7M`lRg=xE3CgIdC)7V$SloW7(4Y1WP0J$bFyMBU(LckUlj6rb@_yHJS`RLox{u^Kd zRzAVZodE?=XQ|3_%?MUxMnDjW)S zgVP>3!zOa=oZ#WXw`8551ac)a@WGQ52s>@RsBfxCk8qhUQSsfL3QZf_cLqqS1IF8~ z<>7)^V&IP3wk?(2^8*Z+zI=p5<Ps?o*a zqK}m8!4Rw~Fm>Wd=3=8|wU4HpypU5wfH}IM1kk~HI{!nIs*Xz%|DsENt(Kfj`H#Xo zuZu%&o%O$V zhsdLpXTk;f6H$nLqgxsk5_DzqU`jf@)fem4RM-lTVj|o==i!mvN@aGkg1ffi&u=iZ zq+jAU1UuAezJ|3xt`ZbDaPEJ{1g+{;Uwt=?SA@|M_qUM=A&Xb~G0#T!#pi#U63!IMdLcNb^i5Ypl|XwW^w&f^#M{wDWulOI^Kow6skKi+US8{8L!GBj5z4GpmxRoHG`PR$u znq8;D;g-yF0;`CS zQQ=+@b4@pC(}(gwI(?D&!g|(?Kyz*IaDgk)=lKEy&pJ4`J7~B&9M>~X_K5FkVV`>w z&?QK!1nNj%D$kWBkCe=>UiS6itK#y%6fpTfUJ*IdFs5Z?HN-4KHCa{lDO1koAV(bd zyRcrrBA<&?-)1T;@slQBKrdub1}I@OcUTtuR5InnLWf;wPuwtJGausVHM&m?2dH#( z9Ov+DIMZNal2f3NP1tNTNM4zi4C__S;L_tSM zbT;bgc<@fPv19;)IN-XTjTxsLO4dhZNYN3UVSTsDxJfXDd>|)_u zTc%w9HllwMoqpJpFiT5%rBY3S5H6p!(NBeIlYJQ|9Vf@WND`rjrdBJJ1aQ(L+h^rw zo0oT+%Wh+4)f`$fTTQ3%jv9A=4@2Ma3z)btd0q#H>39m}Dxh$%#<4@DXlcJ5dr|=F zd%gOxIbz^oE!!VoPt$m#wDD+bE^&6ehg_ctVcw7TG(my1-x~ktaBwkRMRza$8XsN2yJ!6a9#`&srVdiVXtz{r>MWL2u+CPvT~E9@g9Yii5Lr;}6_ zOaKR##)klA$UyN2Nep)AR7i(ak5z5xIjqml8mkJI zX)u{(@6S+TB^VWGQn_8vce}WcnmYcBW#=j*7HZTU0+kjqbdIQ`Fs8W*9V`|jr8s1Y z=q=8-;m#9w=)&JdY_BO2FlkF{N%YSWjS_VoeBf)=jvUyGZZ@h>Ez<^aKQoC39H8fi zQfkFgSb}#Ht$y!WtAHT}q7qa;GG>!wg3=ETq@3h-Im(DK+49Ur`)YL9T(Q#FDZRbD zxb~u{%MVss4w7+6Ejgt#~x9#)|^Uc$F zF&frIk|}*Kiru3gmi0r)49*`8_HMEoMactI-CwY6mO5~v^0Sj*Ci2I~gtAtx;2DkX zK{uo0Nb-y#i`&P;rnqYUhrx7@*Hin)NTvf9A`*Es(Qh5XW{I2Q?8n@FyX53Ue_`N^xQj|5B3m~v|(P!7EK~rGZrYCM(c_!1(slmg5n{4g33Uaig}I*YqVW&?T0bV zTA|yB@hmvgf&+6YlM!>bkMzxVOh-*;bbzX2?G`4+W%k^1UuJZ3nhNdppv5o3kOsM9wqq2FC*x{oCo11qS0~&1KhhL^4h8 zs2mcsP)s`E>?tP4eKo)%AGJPy#GNktoGHh2AUlE0V}hKCT(?NK)p|zPdhf_JJe@P+ z|DMU?#vU+-ZE`_zD;_-|7}Q@ITDNcU-M@ife*8y2^5i5-#A2~d9_k>#Q7eMxMAcbX z0`>vve{EdQWvuWJJ1nqk^#_vGE16+<>wcY&p1UEbz-VyX>3q4=$h2Ku3kUlgF!E_D z=LbXdDYfD$Dn$;|)OOl#2)+U%kBw(45qSJxm_tG&NB8Wd zQh0*t<4biPy?xbajSgGZF`;LtlxNp+1xjkPWLx(ujU;3^b=wgd9O-ddd&WV2Dkh~H zBsJc;Fma*|({E^n-?LEvd#7BQ=XxxTpJ#8cNGuu8lF0moTn!PDfHEQR9>ahOYHoyo zU{GIxd_z;Q?$VG1mi+w_eUX z>5zrj&plai5RF3PULQ7QWOfADZfiN6_GLxZTW?9xwXVTGm41NH8aeWuN$`I0`V<)8 z>zB9K945#@fm#a2f?)hR>AaV?>GX79f3e(mx&(5zcs3H{KoqLgdRTbomdtDQBZJDfwqS(^@AH4_n^`H2Wh;{J-m>%)B-Es1Pf7~hnPlYgr=8z( z+*w3PSm=0o@%kABWp(-EFM%7)*~*F`dJQLJcz+u%t-E*^u?u53K|95$*@uI%*0Hjc zqnxQY!Eqng5V8y9s^Gkm4`bT3KPhw|=$QaOg4hQrQ>&uF`~RG?uvn@IUvBQemAJn5 zeBfDkyx5;Z{N;WB8t&>oCp7`pbG^WH3HV^$MwP2)*JjpU{SDRpFgAaF3!tLf18#3; zrUc@T_IGVfZ_tQ2LCcd9@K7ZhH4KkS*KspH#K8tvzF+}X@x@ciUSqM;{ngu-XnyK1 zFM^=t)_I+G!}>d6{OnKK8erX$dxJ^GYZ#ND?lsRJV5o8>AeyGz!#XY(NydA;f+;$3 zy;&nIBp%0~y2BcL+OvpM+-q?n$s0%(S8Y^051?*8A%mZWW_Y9UI9<(H$n>fcT}-yL zP&OMc56kZ6H{l<9Ui@}++q(-}SD%YJc$vvrv2frJFMAwPTl2QEx7a5LSUA>nP`I~;bs5er)n_Y-tViUVx~HI+2mn`TymDFTnj zJ`p@Jr+e6H8#WWLkdKj6z?fCz_$$ckOMUC0*YAh2@cN&l3^`mLtVl~hH5!}_2ut*C zhiNyqrkW>z#TsP&sDp#U58SfxLu(fR8idiH+QZGU5GbLu6bhWZ+I$MFU;YU5AFGL+ zF4b`=-<#3;F-0XB(GVSopWc;Wyhvw>2|$L8F#U{ZDI*C9BB#i*9XCwBc)H{|MM4!z zP%Bx37DbMNshc?-jD#svTS}qMS7N~XAG`AWLAB?&&;Kk`q?pm^IQrEy zC%49MF60PQTO02K@ZCSikhkduopI;b?q9vRxj6K1voR9nKF;ziR>r_O)xr~I=DAN5#Qw(C6D}paF*2N zjUfANkQqb_Uu_Qa(_@&yPTksF~BFMt>(q7jBC$we}~VBuFQmB(-pMp{xD}u zf*n)$<56TVlUibA`Vlmjj{HL_HW56Q9dK;Z+5@tdV=YxDiWz+~K zSnSfQ-Ew=uy+LzY*lU|C0g4IaLp+8gX^y4R{%XzY0x^r3V)c$3@fa)?4yd%Ua^vNG zzGQv`56hVq_&^`6u`@jC-)5Ah#+gq;Cmhfy&aP*x-SE}Pp>h-*yyy}l&i1{BHa15~ zwb>Ipvz1Q#x9<$5U6DW#&Tu}wSo@3^JEgWyL@ z_qW8{!e%$=LYV~o*0aCXAMajgxZg3Zc%Dgj-u_ece!aVMf1V%zP9(b^zneN%LV0P9 zDBme2#F2udZ~RrYC^c<-t~3R{93 zePkc|@~oboxa3{>OG3!M+9qlD;@)uMlbQg~?v9q}@QX%#=mTgFP$Bqb`L1)S)Uyl4 z(AO;eRB{!{E#{cgJ#S2>%XH{VB5>hzeGqPSe&vE=%3b&V_2tLa&7Qs5;mV`$+ER&p z5wVUXl)bciJMBlaQ7Fq4Cz{cqVYafeYDS&c3zVIXT_11P6wIuAeB`qFZ1PM(GQ@O& zF0P`2scHESn?<3`{w$-m>kg@@E%P{XKDD+6Yc?kP$)lu`8Op)*bDSQev~O(hanv=*t2|pX0J9`zgwQ6(*us?Y)D~?s zSo&aA&V`j!#h#x2ak~S*9yGLzm%m<&uSww3LptM!Rtq{nkz8)`_m6zK%N8~aSV~IN zc?j(DXF#bSr;XrN5420XJUS*TP6!wOTu`jD%Y3){1wEC>GBy}18u(;6DgqR zY|__TFU!B_$o&G=3q5Uw25?My?tc4@>!~L%fHm?#E-43u!9n#*bZV-Ul@*WIO+Mdi+kHjR$Yl)fu1=~>-EEjXxh}db3a89dZh`5;ha}`{kj;l;(#x7$A0isf}`DdL6DJnG(C< zdQeCSCwTVl+xKi~C=-Y++SuOuLQP3H`70)TYWL5GiuoUB6+)F63|N65!KrmxhSl$aC$T&7W0fiKW6+@0QbXpp?xR`%z}SHDB3 zOMllaSgkKPt!zI1pM%;JBj89U9DQKjh+s8Y5i7m&`1dRv;jh{2pgE(8XgEu&$|4TJ}a@W21$`GP#WJ7NoqAQgiW&M)}L=61vdUD33A&}!mqk^&7!t}gN*Vi+G04`j%Kq*Us zYK+9>%_|{iO*#wGF2vMs(Whdrv(jX~U;exS>i8NHtN?u)Uz4dM%ZZfCKH3S*#e9vW zBmPjFu2LY1?XbKfz!~q~iB9R|?)d0~lqiKhT%VzOAKg09+ zk2}|PzcrI10E7cZI{V7vHCU7+QWOQ7UV(B`4p5+ih4TP?ecRQQ)@kR^5uLp3th=XTx<& zK?J?FO3GJ>62Ss=USglo)a!wPlbic1Nl8j->TE_fk^@{z+&lV_a94toFEdghHXt_vbTnRi&Eu>=eMx+nsi~^$8(FOrlz1+Qks7DffMTYr6WKjcFJ&Xx}d) zzuSBl9TzN3s^|MDM^6Zl;gHe`rl>9~xPRTpJU;t$JA43hoDhhnvAPcm{!h$mLK-p9 zjL1`tn;trF>B&kNF$V{W#!|7iFqI_^5y9DtrhErgSNROA}Oy)TQx5#0-%1-uBY)}Vp|wCvrOv= zI!F@(#&T7icpQ4Ho~dO71+#{9EaqI{JvRo9suU_@Op+WgBAu&p{$ z3!J#(WXzaF7=cR>OIApi#i2kXT7yuagYm<4doIQ#=_>P?^yp~4MZGE&4#TVCRkae8 z>0)&u0fA@tH|HG|Y<5@2UrZ+|E9`d^fJNaMfQZ{YU81qG(#oHp?MhkJa#L7kS|S>b zBLXfI^X3&K{=09WR{xfe&~v!d2&j_3doz)QLIKB%c2W5rEYoy736YI{xJQY<$gSzV z9E4;L?@rU`j1Z5E7<67qUY|^IR#`6O1N+<<<-jj*Y#$W@RGGGKLE6@zG8IsdZ@XBy z1WdMKB}l2NlXV%s&aAf`K-bUfa) zzM`b16e+tLYmmmh^W+DoQdJVN5LH}=Kf-&_SP!tF!AK=B<@V*pTP@Z_0kiI`6HOK< z6oT5?AFW%i$#B`NV%d19&8Lgo%&MWc2eoHFhL_XS9BlVTP_H&qHcat)yj^+wk*DtT zTtAXm<=UaEzG`o#%y_LcxO(|$zS=lUK}TgM~dDv4{@b-q>Om}^4rl*;_&$3@6y%8dMgxx$3tjI#q!Kwp&-QUGA?8( zCkqc=rlQL9SQ<=SQ;QohgDs(~_HFCR>!3h30S;9YRtT#78?Y>(NdiSet~8D?!|xuI zRC-!IbLct=i&U{v(NvXXf`qLtilL#N^)msJ!|3Q}vC*Ag?j+)p!dhs?`+Qn9#%iBM z=lDc|^wnKG20y2K$3_wIvQdul@$ufFp>VFbz==nhP&~fpOz{qJ{}PLT8B`_~rF@?l ztI?uLhNX3Jspm)=Ry6-DOn~lZ7hJX&*s=PZfFCJbRA^yR$(}2%Dv99BKLX{`2|A1d zqGIJJ{N~K!RGySGRNIVEvOo4YsWX_hJ<_&cP@Z}HZGH*#Y*|ohfPQ(Aj=gWYTBK}7 zG6gQ51Se+Hgayc~xytfmCM;pt+yN-WpT&w`-{|WRJ&BlAknpNP?ZYMyoco)Lc+6Tg zKt;J%{UKH=4DetHo^r@$)Z2jT4#V>mC4O89TY5rkv!%tp{qsqbJMVEIMb#K=8kBVT zk``7(aI|3q7!S?0Y8tC2y(@<0q#&XMz?yUBMicY-QR(S2uC82Qi=@$RQkxg%FuaMy z1$|JQ9xP9HNJvQCcBva&r%B*So^H8XB8w?1v1k|pF|jWI#wuim-w%MWF5AW>0Asov z8jhO@{2<{Sspdi>lL{)T)Owjo_-{2au!E2`en_tz6%N*hGnFU_!w<86(>@x6+X2a1 zA_UjyJ^_MvZz5h5=sqxoJflp34&w5_h-p=!=s57Q7F_zq_5XA}elAA_S4j1gb)G@`k0VkD4q`kkc(St^(r_jB$!FM=3-%|HuHa1um z^Waa06BB!hk?#HT(>>l~(BFv6vDTkmm>S$wgr_xLh!y#9B&4PerqF z>FDI?2-=idiK5+&pL3=$(P3aCSU(Xf+9OS#RYe)eGNt}JwU;ivogtAMAQ$xMm#mh! z3Q$>ND1%==KwnF?K12)zXh~(Y{c^S?E(4h} zXmGGsrX6|xvtOzqi7uB1?yY9D*`jyes@fi*hf7>%fs*uXI@-g_FOuxVBn^AY8s}Q< zoYH2Bq=l9*5o5abnMfHAw)WH?&&Xh0wMWDGHC-9S#YH^_cskceb>MMLAH{=ud_hteGE@%^66O)T&HSASD4~`aq-DQ9oXN?zw!-yq%WNen!tT za(8`XH&s^-w8g&J*ft*|Or_fo<0WoRd9o=ISz|#fN5(swKyWGS`v_;Al1ev0zXp9hwD7Q;Ugn9RGv?an3xSo6?sMrEy55jJ4AD z6_Nosi2!ySoS*J4p(3ckSY7<1?u)Asu8>`mapoo?0OhWJ3w_{rjO_}2|8%C^Z`P&C zybbPtC25i!?16DYlUxH;YPO0N;ktRx8wU{~!1`WeP{S8&;jc>&1S#n@kun%Iw;rpN zr6<$m4N&I4>!dDg>HGTNfo*%8yFcHI)GX6e)faQ6w*!BH&k;1Gw{^&EMaWK{(RBCx zZqsuTWVclYCu}u)OXRLas)lcsIPsHkZma0R^x>TEf@#wGB!k)l?<=?Fc2VB z4pLAlsLyPNrbcTl;maQW5or@$M&5Ecab1US5#l@{UHtul>YCNjLoQHGU zuw~%r1K={NUC`7vT#5`$Xgu&6A4!__`-^Cm&j*7Ah9_k=Zl%}HRFRVvdLq)CkJ|!g zYn|}1Qk}!Os<>AgcL54U z9tkmw7MD}!=EYB-*TP6hSnl)NeB*n6K|dbw#LDHGb8z~4kQb{!{-qe^oejVpLqt< zTSADqBaC*nD=T=1l%ej61Ma%xc7zcz6SvEq@TFDVz4&9}t?lhf%RQCxi3wcR%o4e% zS#8HTL!R?VFAAC;4=brx_*%%YnMRD_CL=WoG9@b6a+H*jYpG9W1H8Xax$3)oDK@-!ow0S!N(+DMCMT7&oljm`rMuf1-WsQS1d!^` ztsbu)3ppsWYEg5N`oGt9P8Y%V=#*w(>U@F3BPRZ$WUf%W48d(|uU$I_Nj#FO{QTOT zA`X7iY^XrLaaVTuHhYJ%I5MEl>KFc}TqW^PY79(t1~BsP8ab+R?An1l4lC2ec2t09 z2AnPlL+5R^Y(|u#u0bK@Bly;xSl~r{ZgS*EgCW^HuPY4W0bkof+4EuSUzee>OVe_H znNTJ&eAkY7y=GK4rB&_gO3F9B+JW1X_e#?)GCKLW9JXt)puCt!uDsAqlF6$9ipa067pz~-#SN%|rWlOS z;A99kCKNc>KXcjKt$PdHdS>eKw&Epmssp}{WsdFe}bJ+vQ2`i*ANZBQX8 z0m-Q3&BmZgk-Lwri>be6l?mhq3UnSxb|UI~V;rcfrsWKjBh`cj2U2U*;c>aN@`Ly@ z6m{V%KWG4>67v^{C`97F$X?aT@ad`LK$RXGF(pr^(x%-|(+|KL$<&_h&=(`=UvBF~o;p?DC*pFad7ZVqMQ(x~gc(X@is+?Vz z+^fPqRp%pWcY)^&O1bTZZvI$Wcp%Bh(KbglyPmI&^*nT!)GkwTC%ptT78V*>{SO_T zux{ZC{N4@V|4O7xabc9S1A|6MhWD2C3^|R<@keoJ_nb^{k+_56npw)b*P{jN*Lo6~ zsRfp&!5gGdKH!CoriFPF^7{ZY8vE zrT~NGJa!~UCF`Wu->mI1b4R8=@JuxLfE5?X)iz=C5Zp=mj>3d2ZB_l|YrZ=Ff0vcfn+&)TGF zSHpaAG;OYe$WQGQ^wdV4k4R*dZ}JzE=NRQvLOLDK`=`QMw<5!^I8np5_MPO<!{<0f^-caG<-ju3V2B@sS)`(v#)fjco|48KGL=rhO z@EPB$Epe;^o85>cQ#UBi+;ihk`LRU^aN4_u*riC&;maRueLwKJ@(=}EzhUwm{(kA- zoWyMW4s_D_14B)!I&o}8@AD_x_UA^vh_O_dD!$T?aadN~yr@gMzdMu4V2j(SUGx!r z2Go!B-)%O5w#6XfyV7-vD&Di2W;Z(+7^xt!{jSM|yb{^1BM_-){p9$3MrYlz@u{0u z)pEdi(iHufE*wlHteej<&1XstSKIx^3q>bd6uAQ)ZL#=0Qv`hYGM8;jg%Xqw-T%tc zTPQzZ!b8nY0_pkjFTb<3J9QnDNz+^MVi$vs9)bpuo+qu zURJFO1x7;u9Lp<7kovy9*xte|HM|&zdMub`!x(~6*-EqgDNn=cV!^UUF>l9_u)HKB z7n=k(4P?c&H94(`bt+GO^pJ^4oanICD35~qQbR_KuM-mjxEd_D!pfa~$0)3VFB2xb zwaa=en7&lb9ZUr~@ ziqYnpK$3S{Sy8k$f^J8*&g{<<`{>z6r)FZu^3ns>>L}0YxkdJ0z)&x{b6t|;oz#QZCa28BOtCzp1I$XQrPD~wDqRW<2&b=S2yz?DX zZx2XW`}5UBr;qL6aQUb6xI@%5BjSXGWOXV+0?ha@r;Gd-2^~OgB4X=mMWj)9&0P zR^p|%?zg*kqTisZa*!5zf#odUYLoVltH$ZRp=PKhRB*tTbE%m!pV#pWY=j>Q&0RH3 zP2YHb`i9`@r<0$buP+53StmK=P?Go4`iO69Bx3};liKxtKTeD~40w*+$ac{-+v#@A zc(mTzS3*j*p9-1EwHlNl7>Z`qTtw-PhxUA+44WhGGKrPrM`U%VC#2PCh(+R4Bj8Sw zmXLVvkD9^}0iMm=zh~x!5l9l zmJ90k?!D3|OjSs|k=CZ?3!l*sAiOSGiVXhr%sVfMmDn#AbiANPK3QKyBT4SxOwbuF zR6>lrc4>q|^9lxr`^3~uF0Tf|YNPGca zdo$sfMSkjhCNqf01|C~UbgovTlBN|qKt>_T)ZwB}!1Bg^MM%(61qh{4o$t-U`)M$m_sz7Ak>BWL|Oh(4YlP;(3xa2Tn zyBVhn?ZI|$&bF;(N9sF4F3l9_=kPU@XUtfQ|%W(W^64qdUP#cnnd!nfd z2*U62XWb@BJfo&)_Qq*{;$qQb+_g2_`7(+FSAZM>AYlzK(-U6vjE%cMYvLt`fQd{5 z2&eJ5TqfUh!v0h;2KFCH8VZwd1~q~#bRg)SAIXU>&rqzfl7R1Aw6G)Mx#> zxkV8(drvNv0h_#n64C9Knx-briw-*>aC3oOl{%kikk0&N!M19{aZa`{t|#o94UM<+~J@ zu8StDW8tIy!5-yd#?qTeURN(lG-|iNTvSL(E*-!rbi2c_$Mrz?EAXnu*UZ3ngV3x! z()w^t|I{TDApgz`{73}GrQIP-l#~=*<6Kbj*g3PTs$P|{F(Ja1DPUQACRK*duw z&=nM-%jYa@?LMa1&kPoxBET0dMX4eC{UQBh4{*V|2dIQ(J8tcpvC0LDSxYt+2rb0& z`4bS!w1`U&Cpd9-?GAhQu|H(s_%mlaS?4m~Wd1DHGfO7W#Z}w67uPLW0ar$?!r;w7 zLdLRfGuh_m=8q|3zGXnC0?)0Z$>od#N|Fi-`g!0{%ln`72{&IP zwJXEoqoBO}pL}`_S_R+`Ku>{<>eS1`Z}N`ZhK3 zI36vBgFJkl)_>x_w$npDXo99H5BxoGXe-E%2OZw_?#lMbRRC$Qk&*zh-ZPykUBZ5I z;P(bCk<*S0aqKWX^a8!@su(&|5T zpD`N`8$8@y0|&k3W|w-|nYf8?!fu4ON9W=6J+M@H0g?~!udP6QPXgBSzqYZ60=Wt& zyKBZo{n|QAxL;ePTv>K^+JVjOd^U%a$lyVPmLHkTP?lJ0H)8W*P09%`cpi$d;tvE1dx$G=dbKtdFTCL zC(SSjK7M>jsO={x0H`uRwmb8FTtsX-NdvEx9HT*l0Ngm!=#}rY&}!C)ulQv>p#z&l z$ZrEa`w7cX!%53z%6(U&kfTxtv2D5l*=9COGN0p?e zekDW%hL4!gAS-zfAANZ{5!6gNeC`lL9FbA&m1`sjd{ zbI$n(Yz+Y$H~vdo`E zZiOe2+m_eTM@E4dd`$iCKa((Q{IQFZd*P z{=On;s3Rs9?K7o@^N~a2EEk?vq1<*3Hc`?X0S@mZSdq?16FnV~6kt-1eVb7(m{Kb# z0naJPZHWnE#gR_iMuyNBrQd85Q^cL$hB-TIA58q2sjaP2L&gy{Go!+h{>v;#1v(Ir zN%OPDinOGVy{rdO_`TCcCj}>9zL3p`$m7Kpx()ivpU`BE=rHj*ExP{QvEUzLCRogl zZ|$~*R@Wry;#FQSc=RJySs8X&IUR$??u6_N3TnD;SVxXtG@a#iNgsk284Wja0;5IL zQE$(lU8&fA+a&;m2l6n9`n*^uc+WK-o$kz)vA^ikpM|tkjTwIbj3e6SNw2yv z1y(~0a7!SN$8y&8S_z!c+qr8(s}J?Aoj}s6LnctK!OtvbYlFu%2H{Iamg8 zlOv0H6DQ$6vzPn*J4`J%kCq0wagv~dYuC?60t}tN!R|^KZIV@B@I6AYJ=`w!z@uhS z;9k|c?o+_{c!S$LPBvo{XIZldcs^I6%{i9J{V`fu(+$~+n@hva&4dc`OTNEccoSr@ zYoWQ+vtGXmR6>&)kLvsvo7_)N5lAwe$<#A)XY9_TXHIvvC7(3dO3L8IM|Xtlm;N8P z+|d=IqfVZr_-p*=v>3_AL#^xk@1ZcmH+=rHy9>2Q?-8+nbs+JE0iyzhHE1&ZMP*`U zb~%_*6_=GYzNj1lg@cRX@W9;)uJuoc0TnQ|cr`NdxOsK5ZeVB#Q1t(kP%g&LMh5U| zFx(+g1n@Zl3X;6r9!QZ&2?aGZ$Wzh>2OCmt)^)v|F#@dN6W2}pJ#ePkc1jDTB+A{s zNP+=$NuZzrM}ou7xPMzKei+E6Z^r&5X}A0hGi@T43IpD7NP}>aJt}LNAR-gy4>ua1o`OzLjY^|I^guqyiopOQgpN;Ie+#m)~W za2q??rfF9j06|w{xg-H>NkBNo9jKIOO9L7Jg!p^hzN2e8ZWom_p%#vr1)DfbtOSPl zSN<#+6K7Btp_CyYAW(m{5D}z?JE69EI$vO6B71}=&RcCW*mYqDm6=c3%vg&-opH&-a1h2@va6=1~kYL zvdN@!v<=X=cK)IM%a#=<|3@PQxI?}`j{-bk!?6ImA9PWwMBz_1~39*$b>Wv2gfrIoG@ zn_0*J5C#;s-nCqF5!O zj0{;o08VYBj@Km`G)7MbrN?WgXB_bk zJ^=BEil2Y?m9N=Ng>KVi@D_ao_kYtXEvQ}%`LrFkDhg#q@it!SGHTTQ@bZEQ3l8Qv zDf1d@cDtlf^#yV!k)}1vc$tpZ#lBV3Q0sqG%XOeyN*NKl58EfvLsh(yHNfP7cC#zE zw2;6S1;iP>hH`?=`oyr&JYX$$plBydYEps<_k6Dhgb!jf=)&Ay9&PuLXT-9h!C6aH z{@=irTNVEkT&cZI-pOChb#q?-G^;i*$_GJo&?@VZ_L0%yd|CS>CIGvk@nU~H-jw~+ zuG`4eL8-~mkVfqS-V5Zzp%bv2-UOq}o*J&PYdVG(&m-?be#*2wjem;aM zrPsiBX*VaAl(cleKcKQ|`9hQ_7j)l>xAA9eogywov{_c5B`kyakH;75t-&NA0_0yi zQ0Aj4)n{=2K43s4s^_Cu>Cg%iN-LIp~COi5yrlEmEHjdT1n z@Pc*(c17`D`WlLU%$Ac$M-?4fbboNHk02Qh$gFc=OjD$)+p-gsL!(Vn|3o6p(cg@Eg zVt``G^Asn#qdGuQ9Vd}8*_&t}T*m&*jftE`YmKHrNuny*#yC9{i!{Gv(HYZv#B&PV zIfaU*pc`TbUPwMRr9VdO)LvSDlK!PbM_Vdy`h_l2jstV%e;rDZTJ}|L;&lB>F~W29 zHig}~bOx!46wF%z?2)cCM*VAX2j}4JCHMYfRp4*+JE=e&-Y}mS|Kgk7&;1^o#rLi+ z>d8;BU4{(D^8`OU@p}IZnIO6>eO-|i7k7TGR*#zyJ1=ql+xO+7(~$=N28zJGFs#nx zrMzpo9idZyw0wI7epnH$9xm$JXOLHwQzsCu4mYy(_0L+w(|5D9%aNm?VoyhdC3M{A zL^WMVl;XtHGvA*r*K|9m2Da-{U~PhqXW!+D7rpsJklSH>AV58zFjjEi1o9X#l7TIz z>CT4_^FQ&d`JZiuxsP~&tf+I{kcTpFa_9uWwnh61=~S)8XxC+w9RfQ_3}U!L?l zaF!3IaVG%$QLG48Q;Lrb8T4+g!lPD}T%;h8r4d^Ibh(fF{uxeQ@N~j{FQE?UVzlNR(7mg^QLe zAQca|Qv%)`4U))f>R_DVKgFp3tI=jRr^Dt;?FXQbRk)lPf%``iKyU!Y7K3Ng=&;uf z_^c<=^@+%JxtKHNwD}D)5Kp`QZ`f5IO!rvKRrrGkDlnK&(||lfpd-V!Z&!!ovX?^p zZ5>=M_SLuVwLPyl2a{Pt!OCWA4kSzf4D_Sdooz^HC^bKIx>^h^fDHdkwQ@W0Fs0S% zs0EdDM&wpw$4QWi{!Mw-8n(mmuVPuJwkjtPv^C{53SVmDP~kc~xi;te=_$|~;Ss_M zzkmOlLcT&n8-a@xj#=6D_G<}A6M~&k^iw^|mX3jrKHA`54tm!>g@VrQGuzV*aS2J> z)(%-@2oYy_j@d#YNtNI};O^pe8G1pUA!xAxkeFe+tX=hgPrFt`4}!xE(ptb-l?@dJ zeSb5EM}M#Bb$@Q`J`EtoWD5h#cJprl-ShN<0kgS2$F74=ovUAN)uObhkW6vd=blhI z=+7E65oo{5tYuA|hBc5whQh?f!E^Y)@?MOiW@XrsvY^*4(5~eXum}-lS{l_@ugHLO zjSI%I3yIF(HT*#xP%c4^~AOL%H0r5G583K%>nZa49J56(^JrR73O?Lm)tv!{RwYW6g*C(QSFuQGdc@c zIPJ*y&4ehR)78s*76*CR`-q1LOUMSmRPRs7I_lW(QVYLra~Ky)BV zwi58ZeD{A9pOlJ#cX(9XnI+PWj%;aM4j~kKlLcsVb7N^~s>+s^dyb8OnEL`m89=FP z-b~lU)^9UtxjnsXx{*1_Ei2=a9>Y{w-H}q<=hDvi|Ym_K7YBhbhs_~e4W-31z>{s*Z|3^^tyv}wVMy=J87i_M@ z=bkgAT9WGO*fHd?c|i38f}i8zqWVEOud&eoS1-yionHO0?0)frObUOXb7!4mkb0|R z4j;Pz`;Dn0INLy3S-1*BGrJSEyrzf_ zl>BfDqQ1|OZEAC5DI&tZ9pJ)6vYwo5e>M^+F0-nXO|L9M9VJe<`@-YK09y#Iuu%{Y#@t zfM;N1ebf0G5a8;(=f2Cdao-Tp9 zl)I`~IfD0nL_mPdeNvJX84xZUm{A-An_5+^YH=|uF)kK0C#Oj~S%bBG+F<@JIfewe zhJ0NKwDDn!TK9_wpUu$7kQfU-vuno>y+_5{-`_tG81XV`eEw6`Whzd!{e6Ai*`c0a zNn2fBWq!*eR}RVoQwi(duknBVZWH=#!=l%fp`r_R)?KWx5&utV-vJcWwr$%46$MEu zL6SCzC{aK_qCx{A5?Uo6kPMPRTXIlAGDr|4NE9Rq0!o$~L_l(;i6W9ga{jaNocHdz z?|9#@|94qsQD}#~*IIMVF~%G-KX=<;?ZLFto2Y!_B%7P(q312|?pww5QUg2wt4MBc zGF7d!q6=M{k|N|pX)!)N1E)#+-1~bOxvsGyZ|MnWo&AF=a>=j&YHEMCG9vkSO+Vi- z){IguEZ>2^YU9V`^mJOKgN2kg(akdAT4ln{q7N?0Q8K!1>Or>$9hr+eo{sw-hU1SS z^2a+V?)wZz25Sv7vp>{7ft@}D?$x9vbUZ=CjIl4R9^(N$gvF%~?lP5ADuNUgA1{S0 z4u8kp5ouaO0uEK;GREMNOzjZgtRDZ_{k?5`ge3I>{>8A*CjM$B!58PBpJbPGG8Pud z8u8HO@g&$G8~q$o1G#&i@PM9xs(V&>P*8Wwk3~jAkr<=8r2yt(#|dw#rK0HW78DA- zD^BJTSNl$MEOg@Ww{PEcp@oG;$mSew+0D$nciynNr>dHfeEJ!S{AT@`$cbn=|0`A< zrt~6@@LR>U{De~*i+q#OPD;mr9$mkopu*6TJrM9|@>tiEBpoS%v*aXRTyx|!JEWGj zwpYr#^G1mWe{9JttU#dZ)b=(bTq+-^W)e2dz}ysden;)RT!BtCpkGlM_`9i*;Wuo={tk8Y>;A`lj;>>VSk(d9{4{Z6ZXu)(>B^>?onF&EHXZ;p8p zVJub2 zMPs(po-BBI=dVPXBPSHg`jvTz3Ok=DKNWC3pA=U&`?zY++}TK@Y$AxmE`ch<$=F|| zJ4`c(LF75$Dv7zd6yot@Fum+4(2&5SX9wLOF$q%B?}tv&Qy}wwMgjyszp%}>CIgzCK=iE;QvRz~ znVH2HM(8C-X=$g0eomq-Hg~8nBvrcPN_$qcim{?65kju1(9nihkB#jqwJntx@s6M} z>B3%{(a|%Np#F8F5C|{y-i6I&{PHVm#4XaT@zmCyVx{?6y^oh#$IWQ%QT1sBd7x$D z4AOMK?z%D~rN3$S&5K2}^{96+VtUjazt`67y;gPnPWbZ}*|XMJx#>uAcgWypSRsE^ ze}|PoS8UH@+5%^;`}xIrQ!}$_0ArRxSciwO5TH}d*>`%|v9&T)IGmylS)Gofw8nz@ zM@_V*rr&H%1>@e%hOC0ZNde0N&%zNmks0pzj*dGVnjeU`%QulQb47Eobin6|w9rp4 zyBqYjki7)Ni?U_}-el)AxNj)h8G6Rn7TX-Vspd-f>;_H1yu`ITT6do{xUa7iMbMd# zEwj;85^@juE<3!8uNmVp)F>uz{e07VubQ-xTEynZ&92t@YxnQ^OB}3Ov&F4)?#`~x zDr>2E2gVeRSxB!=Fom*=4VY)wzG`QF*-I@)2@;suDTK%OhzS3ngzT=ap{FF>+HC;= zkN5?(o%A}goF zg1?5wpbVK5ckwhywV^;_N+VuQ>4opqf6ND7utb|&%QFp+j}Km5eH1JH&ShsrJ5}+u zUjw5v$-&zF1FyB&-sJc1$)O*VWoC9Z*QkjKa>DTNaD;LM{bFA(0RS_1RPa)7N8yJx zdR~lkzz+-zq`79t62YN?|F+W?3et=T?AKxLV}TgbfO368Ms*jm{mlc_s`fU|Sn+-s zll`2uuu^ z=hPKHoLcHuyDuTz!vLKsTyxmc!nL5eL@Dnj04sDChKl?0COeEA=KG;I?rH@%u>o>^ z9^3KSwBwe5jTa6_9YH+1@tmWHi16tPBU(y?M(F6qrNvUd=z!R^&==RQ?;J^rus$&n zl2&3>NUZ9A^}DBl9-N>3(U+ZoLDK2vYL3~K zcDLA`qP1WB{Jci*Gqui@RM7(_t?vG?nbgNuGTYdjR#I<%wBU^ud^bTr?yeen+)@eI z#0x|lsa)uL@E5h(doIDrd2(xOD{|;o z@hmHdLwx5OnA|Zc|swTtFg|{BP!2 zwDC*%i$2Q4e2j*@yyVX-ODKDPwAq|6vC*G1k{fAy&7Iv= zzO>qW^EXi6+Q~WCS#(G^J#jI(YGUJH#6L6~6uKvrRaDOOYTLh6>$G{U%!82KbHqG+ z>l+m2v8mo4L0`&XoPPv^`GS>4pStKu%o;{3A~Br4fJ{;>`kBE#wz1>Mnuj>oM7ce= zCL31sB;q?O#{Lf^UEZTYhkCggH&N^K^uky{Fnqq@D7V9trCnMucrhO_YFDhRq2UW= z1X=ehbg-_+D@I1XA0-K8(F14**D9?TtGrLfB}WM|<)GBm+TFS+Q&}>`2BTzenU5!# z_(){Q*5~dkBRS8~o#i=Kfq?qR7W;tmQy(kRa(pk8jgOs9JcpW-vvJFwmjcaO{HQ<* z;bA*bk9+w;k0bLilj7DdFWGZ}GrFgyHc|P6;JxNM92U%~6c+#u+QOH$(C8=26Ab`@ zi2uReh0&m)i*;3EK=qy|#9%usUhWhuQ9XYq+b31z=R9nPAdKqlEW%lilC zsSc))e@LvHEj!qFUF5V~ctuy4QI%uI{9aI6p;=mv6wKc7ApF4ZuVhv#rBhK}wAZ6C z^IcV|;2?PoBZ2xP4ZsQn&5W-qNpvHuC{#GFP@-i6V6A%mXRkc`-ki4n<;$%stwOGh zckJ_U!b4pJ3s4G;rT|21eSWaFM6Rn2#5PZ){i((R1&2Ml%>tb)TcN8s5Sm%XTLecu z8z!o7P#)|~m>Y0kCFLPlVd-do;?J0$%rikCh^Iue9W|z-CSE$MrAs8P#?iiVRXT2# zIh(s1^->7Ku}*4^`s4*&bz3u+`yTF8>KA}#x2aodL1}DG`h3?y14_&nOy=Nw0C)CP zP38QnZxt0NRO8duHcIrJF}@G4BMn-mja8|lV`9eE9QduNWKr6!X1SI6ACY3r1f;SA z(ew&m1cr{+o0z8aISk*qYkkeSWGJzPNtC3eWxL$k$A?Wv#$YhV?ty<#q>Fz?CKrNV zpbL-%W-&2>;$qixbcUegA(Zm1xXGHd2}dOj2`_vUQ7gfW*4NM#uF^nx%W$Zjon7(` zSN@4lc}Ua@FPwMqqg9?!$_=lY8cot>rYy_nOpT7NZl01~)q0W#1?L3~8&3$?=8VX`Qqqt8h4<+ga0 z3z3yeTw}9DA4*1EXh5ON+~SXEX!J+dU%c)zcd8Lzf8q^Q^X1iMeAsNSjyUZ*hN-xs zeqEPtM2dXy*p#_gCMA!$-aC{yKOG~PP8%o#H{&L6MGea>szhC)D&6-@5%dr5vdxgh z6?S!L!KaClq=1i~H(&uYkatVO(dp_`W#rCT@{sayg+vl?tFkG@+7$5DEN)~Ppio_S zilzW#yo#k4;myx)|7Md=P(by>gAAcoMSg+VzYagM`zhYm5mSpa*@t(-ge6g^D>jny zs4gk>EY-gGVxs3y)3UQAdB`;iS{gafd7#%=fwsBsQypGbTohupLCn4$ol$}s3-<8Kmz{tI~9hSA|>HF>#=54c3xh- zZfz9mO;VGmK%VrY%bD5PG6n|B&`d6wNN#3sPC;@M%Gs14O0*x$sDubReKqbvMs~Nc zl<{K$dWE2(#bzohD*fF}ceJ1^V5s#u2d(;_?OYCm43|gu> z22dqa+8rb#wkt~-5K{)$U25k?R(8n;!LsFcm1pwQy5 zZO?uFbjN!3{TWA)WHCC=y#+qHfqZzR)BmB7h@Grmu~)5t{G~_ zaGul&R>Qtn_FG3Fm{{acH}28nDkiEu2MXLfpSq}U&t7(VB!?Su?lca3y0>=6+HPwy zvPPGG6ueEOh3Kmx7f8r$e`2lpiab9j*`WJ(h>M-~UhcNAu&NTgXl=*a2>te8>cpZV zbu5-Er-48#S^-N>9jw()fNJ{v_u>%r@~blB)dN=sM7V!3gaijsF_R=kRCEnMvBKy*TapbJQ^LUq+ zs*k-du^`BXloZCVj`b~{Qr9lPgWTy~?c5y6Q=`qw* ze=zuhS~H|k_O*|Xeut5y78Itu55uk3?naF)HUL#{zKIv+1w&T{ZY(^%pkQV)DqIpD zZ+_9f>!*UAC?&dAm**S}Q9^QK)(@1x_d!i$_LNbqo`H|k8bX6UlVW%qk*1U!`=v|R}zKJ7-A$cKHUUtD+4 z%hyaA;N=Z}t#e7dA&9YVyn(84zic%f2jfB}~(Sfhs# z4@ywa-U%=18uJbSFPF!OxyS3MbpjmmTyt&I9luqZ%@?^j2gM6{H3yLVAznu0@$>fF zMuk1~QL-;;7Y2KxCX`-Z^A~ruL%)z9NANsuW_y!jD@n&4)8YqquxFTM13g(9alS|A zI?PsKP~5h zT{!qmaM*=_Ol+0BgRjGO``d%v1^ZScJ!#z>RM$TLQWZJ?;kZ01MW)x&90j+sF27Z* zx8%t^A^M>H!)LMfW-@55jztb~9cd}4XC?kVK3vGgyc?a0L?P6@W?0wDd~dk}So2GY zwWq0cbjc}jCmI02i7oobSRI8LTFEK|{n}J_%WGC)Mf`CCBdw#P&EB1pPx*p2Y87Kw zIl&w3SgF1H^FwCj6#8OwF@}^?ahK{>f$GO;{xx?B7JpZq1R0BN=jDplXH>GEN{XB6 z_!RGKOgPFbe3~qq&if|x(_0o59uOcCR+6rbgN(BV+mwUnV(DMq9ylmPK6c-xWjyF_ z&9!V2fQ$&!QNTI4wAt#$B^vdy-{Sp%g=tofERr>!0yz<+qd|ehM5+9EdFK3`NDZ&U zAHz7=PhO^H?BO*Jrtd-vgsyDw&RgB-pc=;I!{!TZUqT7}>#`h034|GUV2}eP0_p}4 zS8pnW9dK40RQz36QJfREjUD&4$Jez?(qptN`}c!;de_L;sDR;j-CmapOQzs#Q2-u` zmV~#Nx_p(AHkmT&$T;1_D3wQQRHKdrcesgH<5p6eLML{sYCO6BM=CCQyR+z+PjJ{v z6GaxoMq2<;9buG{4ga;#vDpVccW_QFU=A>9VI|}Gbn)x9DJ*D(80Y0GtjruaiPOJf} z%rj=@qka>P4#=e8TYu*BN1vDs01ZV+ve~U*IrHFGQva>*p`N__vxbQ$ty5BLG$`fK zE9A(I;6_79HaHxClC%Jv5sqb)ls0FzoHx9}wrwU~p6T$PP*5avdI|uT zL--62wlMk*xub%jVbcz(Gn0z~?fm;VMs-cu|K_KFW(yTE3bfq|Be~85S{&-$cKH9Y z3iuHN^$a0bZn6ABeaCA&iK;LaypvO&daGLs6;5v`*RvYBd{ahV)l&!K>oYK6TZ%BH z14NuHu5UN|!&Tt`tW|NQ7mm6^PEy9L_*6vcG?;!4$&ZS@o;v((3@ zGR!caK7jR9{JVMl2h&jqgc?~9Uw6z>8Ag#t z4_9szz&*k9tcfl-k-%6#InK--z6*?{fb{?&k)r84)yxuKpER|ZyyKRhb|JK**if#} z*9ONBLNRnIV&TmWK(#vsuS}VP(NK5G725}56d_4XxP{a8@Mfqd;4wJI!AbxVZN7b` z*llp%^%j;v0B!+lRPT}f^}@}i8nSMzoK)xqmkGZn+m^sO8o>wrK@7rArs4t?H2~<8 zO=_YeJXW#P@r2peZvENljj@fbT!R|fG+}2(!RGBC;al33W_Kgl%yC@LZ&vop zQ+r9+o4@@e+I|8cGy+)YI? zE}?OL@l`(Ob&Im)dOGz&D~4f*iIWhKrjkxvKiJ>P1z4`f9heEqZl=V^6&=^LZX5sz zUN6tU7jP87&)}J0=xM0~ObeKzjD;Cq=K9lPnKc)aVG^9^6AA<2a`nX8m7esXC6R*jS^h^Rb)l@ zT{dl?El_l+k^tB0dBy0<=^=-SK!nF^b}8uw)}9H+)Z=^#Hz$}5a4N`SfWKOcm6w!& z_Vhy0WQ3OHU>A7Zb&pMfEb4Nc!}xJrt6R~^SCL%s#{-=o`^?D8+jDz%ZR%5%KiFkP zizN=u8kAo>5%iq(+iK(UDqZCUUmu@w01#B0nuVYK865u>E1kM8)IqZ)*pV+mvq8<& zN+Jv~!m(tKymhscUVE(wf;D^?b08Z;Uxgcs23l1_C7{YnfD(_vycdtbd8@sVBzu{U zF2kh@CB)7f3w2u7pN;?(1U=bfukD9%=A_&iZ=kcG27F1CRaH|LW+(x}0v?Nq5b7!x zL>^1kA~6CHz`7vU&+z+o9eJD+!hroiz6sf7cJ^hkp_+hJ$?B7WLmn`u5pz3iWvZ3= z^ofuAbB~09UdBVPv9VP)hF#R!L4f1MDfr39Z1%HByerkpN@_|9AeBs|_KW2|*hZn_ zf`;Ezxr_3LAvBP|%>aVhW@&|cd2z+<$zCa0jiD-Q9$p1+?gcn8Iozagp-^Iq^76!P zuxj;(ifn1Fnw>UojSFPj9X+<$sN`nXNce%-((-YNTfv%s?)E_E&`{R&3YYqO1h{!_ zZdVe6!Vt#9cDGqLzxh7ShJ{OoI=6-Ge9)AhGqbLrzOJcl4PK1+{^uZV2pK{+n zhVuo?F5fmAJ8sEw=FAxy;YX(T2Eob|4Nz@&s&rQC?BBp}SJOMfPD?^ubYlD&mYc8i zgq)OjLU|#m2H7-TfpkHrGgYAmkcPmgPw}BDgQj=9{{DU;H_`o#i~^(ifsaKq8JRq= zY;n!4j*~BozDJvT#%sS8cXjfPw}*XM1cFtb2OTW%dw|AnzZO0N{Q%`@p-GvKuf=KF zozdZPK6+O^`;NWd&Nf-QweEc!i2dre%xwU<364(c4GwH{qv7)uEtA5Nt!vTc(FIRn zw59u2(|rU2p5|gfN{Wd6LM?#KKA_(P`5jqzceevH`R6{IQp9|?3yMtAQf$!9Vg(bt zwT!E)7*5du{k8?hZflwM^}rGAoy5WJl!W!(2y7~Z2Z$cY^G#ZVwjAx}`tWjk{T)}n zC#Izl!3qbxdJU}H?r1rv9z7yexdY9di|1$&mDSgR&BfmWZ9m@qcHgtZ*;sd7>_XbR z?1rBvs^eX``7>k>1^E z9%coG3uuc=i&&Oh#-K+`%gE^1mA-+3j&8HFu`}NvZ@Dsl5Sr<3(dLS?4J~2%l~gGJ zU>hPK`kRoVjZ9ki2@pAisQw+XD#+qER3>Qt1xf!^!2d$1b4pOC`P_lItYDr(0ie6sW{7Vd>hBv#RY+GX+!oIrW+dJ#kH0fs!&@f7P-tI7$g4Ywofy=my?Sd`tSGenv zFOUfE`~bq_(W@pTp%)?tnH+MTS7;IorKg3 zQgb!S`r)4hGc>Rsf-6Pf8=NkL>6lgexw%hEWK?N1xxXih0ueF3U%% z$A0uidE-s-XJtD z^XT86IdBgYZZNw$+?r)HL_wR3`WH^-uMNOzpsKj)|Co90!@tA4zxI$0ChUfrn>ZM$ z;TSuNT4eM;$6;a!+{X~VWD*H)-Vnms3=dmnwiQ~W*77sKdE`l>Vf85`(I;@eoN0ym ztyVBN271<$uZI0E@jIP*x#;Bv-+#)oCR3Gx)59&=UL9vn=p*n3pWIu(`2MLwpvKwz zAVwihI842^$K5{YB#?e-H3ErlvfD72$Ahu77ffu_hez;k9&#}V)un9xYd}5$dPGhn z8DVr2VJP=>gc^aMQIH`N$&HPIEkrxbo7l~pAEf(tg#52tSL)Bv^h(@Sm_@ESf>Vo2 z0(`Xch0^;xG?HwmpSGJ;R<%~tR!r$utKTjpW{=Aagu+!7*i`NIt+rcUTM}u1xYGJXQR2=FaM~JD? zVt@=lYiqx=vg!nzj-xQe3L57lg!aOFWFvdC3EL^BSgE50@4= za0gc`?!>C-madJdXdL!NGO0ogbL^Oi`LT0 zTv!l*){k1;rjQF`1ubHgRUvL{t$LY5t}xVSCjyux7(qR6F96ac#dz_+OLtSjRf`TH zdlBf|uh=Byd2Z-y7dI_;g=Q|<_4B>bw0l`XJlN~*<3_MEz8%$DX~?T@)~G_m!$vmP zQ=St<3E!9~((MA2dvDtRzgXkC=&Rn<1*EXt7{UQKYk9itCk4!#xQKtJ)DGX{7d`<(Fofkq z&}W(pq5pz`{k0cp^Gi5DTYPwR(Ai&G7z6(M6a-bjsWRJ0gQVfWQu@1>M}I+chlv;t zOG#n*r%>6LW_1pU?D%5H3#*Qqot+p|{EWfJu3o)rQyk8qf{U%IwZGyX3_JrT`&ePj z3FtBL>YT<+;L-i4iOctpNuCqHeIxy}Aj)>Nf&k{7y@eQ~(mfoCgHAg93>RWqme+vY zMZJ-Dpgd+X&wYg%{@c&(T_P_@c$l;Stne_`?o@f)$98dnZmPd_`I(Q?FBSE9B=vh- zWEW$Ir2h*$3N`Fcc+hCOKdJ{L1mDGbhXBD}x54Q9s#m+Asvw}e;s3Z89K8PldBWxB zGm3f&O0MJ-7(bTf&|n`Y)*ves3d=@Af|GVra*b|ez~4@UxO-WG=Bb1NW;)p5B*of2 z+zEn7R(`Sg@&aIVmcrE7mfQjRu_ZyXeG{Rz}R~Fu$^~d zq{ep}`42C(Jgx|(6QhnjG04t2ROv_n`Hk^`k%r_Rt@FSH+_T4}ZlN4>)id=4D646+ zsH=B>;ua++5iU_oDG1O2uz51MKM7<{9W0|8Roxx0!bRvV>c_sxZdi$kc4~6Ot*Imy z$`eQ1=F*3VYDiC};E^DT7Kmk7U9GpuD4FmbHAs*cXg%(LQROf{K}G zKj&$Nkw9eI-z-#BVet#4`BT@Kn2@{svfqEU?d=gcxG}v;nvIDLo;~fqV65uzw$8y* zT9Tu9>=WCIThY0uYOg<%_IFrHgfA;6sxQ3{!V-B!Zk$N*`4xE(7R762vDd&+gz8fS z-P19QN(!6$>6G~A^f~`dO?WT<{pk|1H#zu9_b4wz%jB@-7`kXE;{B<)f8-kD#7nim zA^xjW6)yGDARK+Ca8`_JyrS!+tEw%+Xxy`br0jINn;gE>w(aJwddTfCdj!xaHa~&BxdE0t>vYH)E zQ;(DRVUI_)0CgCz@yh=TO#^e*=rl$AY}m?2OWHBMpvf>fF$!R6K1z1~XN>Q&G!uuz zcvqrA^S?9xK;YCyZ{j4OX~uRT{%@#!4BXh^7hp?Uj%XgI)ol7L z6uMWVc(q3;xV|5KA!TLl_2MMNPE^JG5%tOhMdJPrdcBrh#=i)shUtg*&&E}kq6~IF z6qTs-pH2(9T^`Fhi!Ufwe8&}W#Xx_{fxb8Wy+C0mS7D|E9E?RG?kp|_O#Yb6?!<*< zO_|HfrbN}2@9)JFs2eGM#T@FrivOj(jqfJOmngqP6}0m{fstarZ6yk8eY4BU_%?I} z{?(?u;bq|R@0cn6zn0HfGyJDrlLIOtE0 z%bU-dR=K}?MS6MGx!~Wo4#Gbl!Wj*+iwtew$me-QKFP(Bf_k|5cS^dvZ)ywp{`Hx$XeiuLj1|E=Lgdbd=PjO8}k#Hps zmN%mnO!SYlru?$s;A3gtVb}M+H$%wRXUA(_89jd3_t-RrK8N9pxC-}gM=&qcvpN3$ z9d^5(xCIegoKBEwN{<4T|2*e;Q`%6I5k46ligZvg@Aa5_-M9zSaM~8P_~qN}+~x!I z2&}qS*j4EG@~ln&oa_GXDz_=0s9=I{QD0eIq`mF_n=p*uJ4)}>m{r0s-p9$O87vOd z7Q1AWvM0RI{LivttU@Hg1BZzL(fUQqc#0+#GITe*kC^J&BgSn%R~Yf-;=*benq_~%L4V;92K`yI1u9h>o#&!-07yyFR-`_#1`;b13$FY zmc6+p6)~a2SIW-p-s8dhze7`sihGh*WiT%2C@si)Vz06Fp32^@!ZIQN2wy~P6riu8AKG3XOnTYi*&Mep3CH}@Rrn_JsA;D&z>5fkwgX*6$$ z`};Rh!m?O%>}14BN0a-mf5b#A^t)4 zs{F@ok1SYH=BNg`ePbq)UOT6u-zu2-l|z=yX(tj0Z5ekAumsL+S;Kv~!{v1Uj~K@Z zkKX*RnMe-PgfPb+e%R0ykY-~Ilh?=Ubzuk~HpR6Z{ThgLW~&L~7`H-5abAvt{OTFBQy z(}zi@{@b~wu|+P$$C&z~BE|p*k~GHm-fdxZ%%miljGIRSTxJ?i`C9k3zvtcHF1p#nKlf(o zp^*QPF1OT~q{h%bdKm_l|DyW;O1|o)CB?5>RboF(d|Ce43;DKjB^3K@{2+G@I}6vu zuTJs*UQA#!p%<*foSZX1xGcvkx%T2%2+|qlcLNx(RxD&TeO>{@r0bK6Vx%QW!Ba7* z@3MCD9_L^mBaYg+e95WJ9OvEcNgfoj61#rBcFMV7Qy8#mj%o zy>;_X?r`B>!%;=TNTo`qj7Dlozze~=9H^N>d-vQTVfG@qV{!HvL*Yksg5_b#d^heA zdGfv1LP#Y?7)IrE-s(o(8?0qv5p3aB1TswPJ7FWl<@!4|o2^j3l4D_L#J zrirnLVg8&Uo|HSxx4=_kN1+z0$aa7Z+It5|Kh-G28otb?qNR&MisA*KMaft3Y^`m6 zP+nKl96S+Ml4ywqqg*Ay;;=Irbl}1@2dIq0QvnQg`|BOAAr{Z2l4DWrEluc;{{ z8eCsxG@%Y>&!BC>&TYFCVAJ*wqfIfrCj6ofzOhuz=fX++fF9WKMd5Vqw85&-p=(3> zq3Ak%J9eaxiFg^3m&&T znex^))|0~@(uQ{z{d$KjIf>eItI~f_ZoNf&DG~j4fOn#x(tkqz;r?{Ia^`12p3^l6 z$b@a@*0`JD^XJ&OWOL(#R3%wK7m7h4gN_I_8w4JUJ6sk42foJ#Q^L?T=0At-iALNU z#y5(t+RTjVWmX(%c?AV7*CZ>F1rw)R5o+I)Uo6jr85KA!^Qz4KvO|8nJHfde43d)e zho@eA&7sYLV=<;sX^ZV%c>ntKi;ZX@3#_K0At~zD+QgeLb}nhLi4g}UZ>qNx$L$)y z%oZ`pU0!~pV8N_R&aIR@G!*s%_sg7Z&;BJ%#w%8c*N5#3*DSwNGu`rhLm#U-Y=)BJ zG?z=fg9VQ-_sBZJ3)CDVz2?>IkKHLnB@VCZ2=G#rH8gtr);cw7%>{)Zu~oT}m3F-> z+;(%MQ7(LX?@CHh9u|`aS=taHsRM6WS$4k5GiWzSh)z4AjDQLO0bE+4NSq4lr75NPI z)nFfsu=16~WGudOJAW-pgEJyw(N)dCmDt~xQDSipOy4{BcBMCmBqIYMhxc=Ca1u%L z6~d1R>&A!qxl*n6@FkzC5`Ao`5OAF>W?QHdWoTlinZ;mTCS62MggsckU?arFqPodZ z5OzhT>X5&#No@nN?KwPszVHCmh*ehEUk$OTFx?Exwq0t&spid`TWO3Mw9xw#4229A zVv80PxhbmbBRs3me7rh^D7kOasi}Rnz_+R;0xlQEth3@IdbpkuE+{Y0N=wo0Q`6Ax z`FUEfaSfxV=YO-WQJ>B4-J9$z*w z$L_g!i4}1nO}9VANy7K~FM4hqJSK_JZ_?LcXRu9Z_LMap3$u#Dv){+pD!R%&MS&>a z?B;mC$~>dS*3YeTp3=6zf4E%qIL2!?r8+z_^ zRl}jxXij2gwuRt(eOH30d9nxQjm2G+ z6Yti8ooIMO<2%bZ+(KNPBWK zLRng}p$-#QEylz7t}_BtGMWSiS{aJ__7>0;|Q&i+^Mi&34*A?$o@d5tR(-lhJo1jsoYma7PtH1AJTcM_{a@_>I+Vk+d7s0Aq2q`S7Hkim|KFt>-TP#mDRsR!o^Er^PN@9S4fMRfp$XA<1@{mL;W}n z#?#cc%T0lP$QZ`l1uip(ARzA)6g3i-sYlLbi~s?edY>udG&yzNtx+;BP|e7|Vs`VF zTo&R@LmEo}Q6T5w2pppf<$&%n{459^MS!xE(DREW&J*(+RU|+B*_JsP7FNvqaM$Q7$Pd>2!mqN{Rh< z{4VK8E@jT_6D$P9XjLs*aypLG&_|I7ek*0-Cyh;^+>)f%t&bP#sIlnvB4dwoX(=p zyESW9g@(iapm0?n$RtVaV6iroYabMh-u}2p;G%VQJUZLtXHhwv5Z~cpK4N(DcR~@4 zBFPwYI`^xBj>SrE_h$0b3*Fny!M>3?6*aw1WHP@$!z-DcFf#vlE$FcN*vBY^6u*9; z?tZBJA$*A*?R)7)P7JD#`TH7MPJ^{>E{9T`N#VcZKL@r~*v$>}e0zDrxo#OKRdK%9 z)O;%rWRHXa1}#5_B{g4RSEza(MDF+|2#e(a+|cP}DE{7Tn8{3brr17~GUXG>x)G(p z?;XHQkO{(y2N2g}l~M{%*pybGY8al#1v~_^Hc)4*SA`Zq*$P@$9!&1Ros3` zEoE>vX3&a_;vG6K_lJ4%Dm)QOB4RZEMH>O#13(`INqxgrdOBiB$Nd-g1Yp64lbUDb zVhU8f%~&~+;>$lz?TI*630N#TVb&QCpQ821hDHvR4;1y z>2AU8&B~+s?b#Lr?LmEZ+t+9?_vtjT!>TLa*UfgMie5Rt!w;oMzfvz&sa|HR#11;tG@bui&XcmuSaYVz9@g`iS1$zSi1|O{&)J&qX+h(`iJ|?bKYyLQU2wO} zsVNmBnP;K$_!;9FQ=mG4=eX{)KzJ+CI*QScSND!aE`8(+Vqjr$sp0)yMNv`NALGaj zMg&|s-^Bx9#DmE!FAT>wr3G$Qb@hGjx%?kD6Fpl= zL(m8ZhU=HVtzgOs-4GxM-<`HL=(3Rd?~v=t6VRv-X&AV0P2@v{LuG_sExCzV$ff;J zIEK+zwB8W~+}t0ZdJ3S?(XIM`mb$L(o5D37?@$oVv+e|SxE&BbR?N7pi4&aeu=Gd2Nuj9j%T4AK#dbsA2!8 zSqoUOoS^2$4P=kg4rH=QUn`rhtqv;yA$YUV0YQ|ACLL}m$U@0NE|n z*os1zKbh|ixwEtL?UqUG=}3;as=Auff?d5)mF9_OtM5rgK-JlP1>(*`J*I;2Ia)=_ z8H0wd(~D#@)Lm~xICe@EQgeqW|8 z1A(_;M;2Q48q~m@c2+3%$z69o*!+dCmyYU&HutAMZd8L_Am}7!T z^&BCO4|rCfUQsv9(TIJiN7QdVsq+J3sUEJkl*yXH*yl1Ke6OJrk2{%JquM<`#6Vuq?0f zwu^&NT#3j1g3hb4@#fxNmxaJBW)}JOvGw8&=1}I~AS%A&$?B&%`?)^@NsPS8>iHOU zD)##Nh6a~a*LV!f%+YDp=0^Q}hWn>$=bpj_zc`7|Z~e|1&x%VlRc5^t;)Xnaj9LCo zrx-OtaD3-(*l+*ng%)19KnV@Och}j3JOAo6&}pQcc3RTErPPkuLtp33dWl9S1uWW3 z24OD^cm`hyMOzp+3m*3RzrzExBNx4r`Q&Y3H+#}7a&$!DCMtjhS zA%*h*~)=7*XoY9|phWFlU1J-%0D<$B=+x?wa_xOARnTc8}%SE>>n0P2?-7 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 15.9 || up=10.1, down=12.3 for subidx in range(ssampler.substeps): - print(f" SUBSTEP {substep + 1}: {ssampler.name}") - ss.denoised = ss.model(curr_x, ss.sigma) - hmm = curr_x - ss.denoised - hmmm = hmm.mean(dim=(-3, -2, -1), keepdim=True) - hmms = hmm.std(dim=(-3, -2, -1), keepdim=True) - if substep == 0: - orig_std = hmms - print(">>>", hmmm, hmms, "|", orig_std) - sr = self.simple_substep(curr_x, ssampler) - # x = sr.x + pbar.set_description(f"{ssampler.name}: {substep + 1}/{substeps}") + sr = self.simple_substep(x, ssampler) z_avg += renoise_weight * sr.x - noise_strength = sr.noise_scale + if sr.noise_scale != 0 and ss.sigma_next != 0: + noise_total += renoise_weight * sr.noise_scale + noise += renoise_weight * sr.get_noise() substep += 1 - if ss.sigma_next == 0: - continue - noise_curr = sr.get_noise(scaled=False) - # rnoise = ssampler.s_noise * ((ss.sigma**2 - ss.sigma_next**2) ** 0.5) - # rnoise = ss.sigma - # rnoise = ssampler.s_noise * ( - # noise_strength + ((ss.sigma**2 - ss.sigma_next**2) ** 0.4) - # ) - rnoise = ssampler.s_noise * orig_std - if substep < substeps: - # print( - # "NOISE?", - # sr.noise_scale, - # ((ss.sigma**2 - ss.sigma_next**2) ** 0.5), - # ) - # x = x + ss.noise.scale_noise(noise_curr, rnoise) - # noise_strength = torch.lerp(noise_strength, rnoise, 0.75) - noise_curr = ss.noise.scale_noise( - noise_curr, orig_std, normalized=True - ) - # curr_x = ss.denoised + ss.noise.scale_noise(noise_curr, rnoise) - curr_x = ss.denoised + noise_curr + pbar.update(1) - noise_strength = rnoise - # noise_total += rnoise * renoise_weight - # noise_total += ( - # (noise_strength + rnoise) * 0.5 * renoise_weight - # if substep < substeps - # else noise_strength * renoise_weight - # ) - - print( - "NOISE?", noise_strength, rnoise, "::", ss.sigma_next - ss.sigma_up - ) - noise_total += ( - noise_strength - (ss.sigma_next - ss.sigma_up) - ) * renoise_weight - # noise_total += torch.lerp(noise_strength, rnoise, 0.75) * renoise_weight - # noise_total += ((noise_strength.item() + rnoise) * 0.5) * renoise_weight - # noise = noise + ss.noise.scale_noise(noise_curr, noise_strength) - # noise = noise + noise_curr * noise_strength * renoise_weight - # noise = ss.noise.scale_noise( - # noise + sr.noise_scale * noise_curr, noise_total, normalized=True - # ) - print( - "NOISE TOT", - noise_total, - "--", - ss.sigma_up, - ) - - noise_sampler = ss.noise.make_caching_noise_sampler( - self.options.get("custom_noise"), 1, ss.sigma, ss.sigma_next - ) noise = ss.noise.scale_noise( - noise_sampler(), + noise, noise_total * self.options.get("s_noise", 1.0), normalized=True, ) @@ -181,118 +123,6 @@ class NormalMergeSubstepsSampler(MergeSubstepsSampler): x, z_avg, noise=None if noise_total == 0 else noise, denoised=ss.denoised ) - # def step(self, x): - # ss = self.ss - # substeps = self.substeps - # renoise_weight = 1.0 / substeps - # z_avg = torch.zeros_like(x) - # noise = z_avg.clone() - # noise_total = 0.0 - # substep = 0 - # curr_x = x - # for ssampler in self.samplers: - # custom_noise = ssampler.options.get( - # "custom_noise", self.options.get("custom_noise") - # ) - # noise_sampler = ss.noise.make_caching_noise_sampler( - # custom_noise, ssampler.max_noise_samples(), ss.sigma, ss.sigma_next - # ) - # ssampler.noise_sampler = noise_sampler - # for subidx in range(ssampler.substeps): - # print(f" SUBSTEP {substep + 1}: {ssampler.name}") - # ss.denoised = ss.model(x, ss.sigma) - # sr = self.simple_substep(x, ssampler) - # x = sr.x - # z_avg += renoise_weight * x - # noise_strength = sr.noise_scale - # substep += 1 - # if ss.sigma_next == 0 or noise_strength == 0: - # continue - # noise_curr = sr.get_noise(scaled=False) - # rnoise = ssampler.s_noise * ((ss.sigma**2 - ss.sigma_next**2) ** 0.5) - # if substep < substeps: - # # print( - # # "NOISE?", - # # sr.noise_scale, - # # ((ss.sigma**2 - ss.sigma_next**2) ** 0.5), - # # ) - # x = x + ss.noise.scale_noise(noise_curr, rnoise) - # # noise_strength = torch.lerp(noise_strength, rnoise, 0.75) - # noise_strength = rnoise - # # noise_total += rnoise * renoise_weight - # # noise_total += ( - # # (noise_strength + rnoise) * 0.5 * renoise_weight - # # if substep < substeps - # # else noise_strength * renoise_weight - # # ) - - # print("NOISE?", noise_strength, rnoise) - # noise_total += noise_strength * renoise_weight - # # noise_total += torch.lerp(noise_strength, rnoise, 0.75) * renoise_weight - # # noise_total += ((noise_strength.item() + rnoise) * 0.5) * renoise_weight - # # noise = noise + ss.noise.scale_noise(noise_curr, noise_strength) - # # noise = noise + noise_curr * noise_strength * renoise_weight - # # noise = ss.noise.scale_noise( - # # noise + sr.noise_scale * noise_curr, noise_total, normalized=True - # # ) - # print( - # "NOISE TOT", - # noise_total, - # "--", - # ss.sigma_up, - # ) - - # noise_sampler = ss.noise.make_caching_noise_sampler( - # self.options.get("custom_noise"), 1, ss.sigma, ss.sigma_next - # ) - # noise = ss.noise.scale_noise( - # noise_sampler(), - # noise_total * self.options.get("s_noise", 1.0), - # normalized=True, - # ) - # return self.merge_steps( - # x, z_avg, noise=None if noise_total == 0 else noise, denoised=ss.denoised - # ) - - # def step(self, x): - # ss = self.ss - # substeps = self.substeps - # renoise_weight = 1.0 / substeps - # z_avg = torch.zeros_like(x) - # noise = torch.zeros_like(x) - # noise_total = 0.0 - # substep = 0 - # for ssampler in self.samplers: - # custom_noise = ssampler.options.get( - # "custom_noise", self.options.get("custom_noise") - # ) - # noise_sampler = ss.noise.make_caching_noise_sampler( - # custom_noise, ssampler.max_noise_samples(), ss.sigma, ss.sigma_next - # ) - # ssampler.noise_sampler = noise_sampler - # for subidx in range(ssampler.substeps): - # print(f" SUBSTEP {substep + 1}: {ssampler.name}") - # ss.denoised = ss.model(x, ss.sigma) - # sr = self.simple_substep(x, ssampler) - # x = sr.x - # z_avg += renoise_weight * x - # noise_strength = sr.noise_scale - # substep += 1 - # if ss.sigma_next == 0 or noise_strength == 0: - # continue - # noise_curr = sr.get_noise() - # if substep < substeps or True: - # x = x + noise_curr - # noise_total += noise_strength.item() * renoise_weight - # noise += noise_curr - # return self.merge_steps( - # x, - # z_avg, - # noise=None - # if not noise_total - # else ss.noise.scale_noise(noise, noise_total * ss.s_noise, normalized=True), - # ) - class AverageMergeSubstepsSampler(NormalMergeSubstepsSampler): name = "average" @@ -349,9 +179,11 @@ class AverageMergeSubstepsSampler(NormalMergeSubstepsSampler): noise_strength = sr.noise_scale if ss.sigma_next == 0 or noise_strength == 0: continue - noise_curr = sr.get_noise() - noise_total += noise_strength.item() * renoise_weight - noise += noise_curr + if noise_strength != 0 and ss.sigma_next != 0: + noise_curr = sr.get_noise() + noise_total += noise_strength.item() * renoise_weight + noise += noise_curr + substep += 1 substep += ssampler.substeps return self.merge_steps( x, @@ -515,7 +347,7 @@ class DivideMergeSubstepsSampler(MergeSubstepsSampler): f"substep({ssampler.name}): {subss.sigma.item():.03} -> {subss.sigma_next.item():.03}" ) subss.hist.push(subss.model(x, subss.sigma)) - if substep == self.substeps - 1: + if substep == 0: subss.callback() sr = self.simple_substep(x, ssampler, ss=subss) x = sr.x @@ -528,10 +360,11 @@ class DivideMergeSubstepsSampler(MergeSubstepsSampler): MERGE_SUBSTEPS_CLASSES = { + "default (simple)": SimpleSubstepsSampler, "normal": NormalMergeSubstepsSampler, "divide": DivideMergeSubstepsSampler, - "average": AverageMergeSubstepsSampler, - "sample": SampleMergeSubstepsSampler, - "sample_uncached": SampleUncachedMergeSubstepsSampler, + # "average": AverageMergeSubstepsSampler, + # "sample": SampleMergeSubstepsSampler, + # "sample_uncached": SampleUncachedMergeSubstepsSampler, "simple": SimpleSubstepsSampler, } diff --git a/py/substep_samplers.py b/py/substep_samplers.py index 7d40c45..9ed2d98 100644 --- a/py/substep_samplers.py +++ b/py/substep_samplers.py @@ -11,7 +11,7 @@ from comfy.k_diffusion.sampling import ( ) from .res_support import _de_second_order -from .utils import find_first_unsorted, fallback +from .utils import find_first_unsorted HAVE_TDE = HAVE_TODE = False @@ -73,15 +73,8 @@ class CFGPPStepMixin: def init_cfgpp(self, /, cfgpp_scale=0.0): self.cfgpp_scale = 0.0 if not self.allow_cfgpp else cfgpp_scale - def to_d(self, mr, /, x=None, sigma=None, denoised=None, denoised_uncond=None): - x = fallback(x, mr.x) - sigma = fallback(sigma, mr.sigma) - denoised = fallback(denoised, mr.denoised) - scale = self.cfgpp_scale - if scale == 0: - return to_d(x, sigma, denoised) - denoised_uncond = fallback(denoised_uncond, mr.denoised_uncond) - return to_d(x - denoised * scale + denoised_uncond * scale, sigma, denoised) + def to_d(self, mr, **kwargs): + return mr.to_d(**kwargs) class SingleStepSampler(CFGPPStepMixin): @@ -230,7 +223,7 @@ class EulerStep(SingleStepSampler): class CycleSingleStepSampler(SingleStepSampler): - def __init__(self, *, cycle_pct=1.0, **kwargs): + def __init__(self, *, cycle_pct=0.25, **kwargs): super().__init__(**kwargs) self.cycle_pct = cycle_pct @@ -1085,7 +1078,7 @@ class HeunPP2Step(SingleStepSampler): def __init__(self, *args, max_order=3, **kwargs): super().__init__(*args, **kwargs) - self.max_order = max_order + self.max_order = max(1, min(self.model_calls + 1, max_order)) def step(self, x, ss): steps_remain = max(0, len(ss.sigmas) - (ss.idx + 2)) @@ -1364,29 +1357,30 @@ class TODEStep(SingleStepSampler, MinSigmaStepMixin): STEP_SAMPLERS = { - "bogacki": BogackiStep, + "default (euler)": EulerStep, + "bogacki (2)": BogackiStep, + "deis": DEISStep, "dpmpp_2m_sde": DPMPP2MSDEStep, "dpmpp_2m": DPMPP2MStep, "dpmpp_2s": DPMPP2SStep, "dpmpp_3m_sde": DPMPP3MSDEStep, - "dpmpp_sde": DPMPPSDEStep, + "dpmpp_sde (1)": DPMPPSDEStep, "euler_cycle": EulerCycleStep, "euler_dancing": EulerDancingStep, "euler": EulerStep, - "heunpp": HeunPP2Step, - "ipndm": IPNDMStep, + "heunpp (1-2)": HeunPP2Step, "ipndm_v": IPNDMVStep, - "deis": DEISStep, - "res": RESStep, - "reversible_bogacki": ReversibleBogackiStep, + "ipndm": IPNDMStep, + "res (1)": RESStep, + "reversible_bogacki (2)": ReversibleBogackiStep, + "reversible_heun (1)": ReversibleHeunStep, "reversible_heun_1s": ReversibleHeun1SStep, - "reversible_heun": ReversibleHeunStep, - "rk4": RK4Step, - "tde": TDEStep, - "tode": TODEStep, - "trapezoidal_cycle": TrapezoidalCycleStep, - "trapezoidal": TrapezoidalStep, - "ttm_jvp": TTMJVPStep, + "rk4 (3)": RK4Step, + "tde (variable)": TDEStep, + "tode (variable)": TODEStep, + "trapezoidal (1)": TrapezoidalStep, + "trapezoidal_cycle (1)": TrapezoidalCycleStep, + "ttm_jvp (1)": TTMJVPStep, } __all__ = ( diff --git a/py/substep_sampling.py b/py/substep_sampling.py index 540953a..6431592 100644 --- a/py/substep_sampling.py +++ b/py/substep_sampling.py @@ -113,34 +113,11 @@ class History: def reset(self): self.history = [] - -class History_: - def __init__(self, x, size): - self.history = torch.zeros(size, *x.shape, device=x.device, dtype=x.dtype) - self.size = size - self.pos = 0 - self.last = None - - def __len__(self): - return min(self.pos, self.size) - - def __getitem__(self, k): - idx = (self.pos + k if k < 0 else self.pos + -self.size + k) % self.size - print(f"\nFETCH {k}: pos={self.pos}, size={self.size}, at={idx}") - return self.history[idx] - - def push(self, val): - self.last = self.pos % self.size - print( - f"\nPUSH {self.pos % self.size}: pos={self.pos}, size={self.size}, at={self.last}" - ) - self.history[self.last] = val - self.pos += 1 - - def reset(self): - print("HRESET") - self.pos = 0 - self.last = None + def clone(self): + obj = self.__new__(self.__class__) + obj.__init__(self.size) + obj.history = self.history.copy() + return obj class NoiseSamplerCache: @@ -155,7 +132,7 @@ class NoiseSamplerCache: cpu_noise=True, batch_size=32, caching=True, - cache_reset_interval=9999, + cache_reset_interval=1, set_seed=False, scale=1.0, normalize_dims=(-3, -2, -1), @@ -286,13 +263,20 @@ class ModelResult: self.denoised = denoised self.denoised_uncond = denoised_uncond + def to_d( + self, /, x=None, sigma=None, denoised=None, denoised_uncond=None, cfgpp_scale=0 + ): + x = fallback(x, self.x) + sigma = fallback(sigma, self.sigma) + denoised = fallback(denoised, self.denoised) + denoised_uncond = fallback(denoised_uncond, self.denoised_uncond) + if cfgpp_scale != 0: + x = x - denoised * cfgpp_scale + denoised_uncond * cfgpp_scale + return to_d(x, sigma, denoised) + @property - def d(self, /, x=None, sigma=None, denoised=None): - return to_d( - fallback(x, self.x), - fallback(sigma, self.sigma), - fallback(denoised, self.denoised), - ) + def d(self): + return self.to_d() class ModelCallCache: