From f027006e9bf543eb1cdaa7fa9c6b9d858331892c Mon Sep 17 00:00:00 2001 From: cbrewster Date: Tue, 24 Mar 2020 03:10:16 +0000 Subject: [PATCH 1/4] Bug 1618000: Part 2: Clamp blur radius based on scale factors r=gfx-reviewers,nical Differential Revision: https://phabricator.services.mozilla.com/D65805 [ghsync] From https://hg.mozilla.org/mozilla-central/rev/c72b18b2226756ea8e861ff45f7255b780b93ca1 --- webrender/src/box_shadow.rs | 5 +- webrender/src/frame_builder.rs | 1 + webrender/src/internal_types.rs | 18 +-- webrender/src/picture.rs | 139 +++++++++++------- webrender/src/prim_store/mod.rs | 3 +- webrender/src/scene_building.rs | 5 +- webrender_api/src/display_item.rs | 20 +-- .../filters/filter-blur-clamping-ref.yaml | 18 +++ .../filters/filter-blur-clamping.yaml | 30 ++++ .../filter-drop-shadow-blur-clamping-ref.yaml | 18 +++ .../filter-drop-shadow-blur-clamping.yaml | 30 ++++ .../filter-drop-shadow-transform-huge.yaml | 4 +- wrench/reftests/filters/reftest.list | 2 + 13 files changed, 197 insertions(+), 96 deletions(-) create mode 100644 wrench/reftests/filters/filter-blur-clamping-ref.yaml create mode 100644 wrench/reftests/filters/filter-blur-clamping.yaml create mode 100644 wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml create mode 100644 wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml diff --git a/webrender/src/box_shadow.rs b/webrender/src/box_shadow.rs index eb8d4d0d4e..c2ef077e81 100644 --- a/webrender/src/box_shadow.rs +++ b/webrender/src/box_shadow.rs @@ -4,7 +4,6 @@ use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, PrimitiveKeyKind}; use api::PropertyBinding; -use api::MAX_BLUR_RADIUS; use api::units::*; use crate::clip::{ClipItemKey, ClipItemKeyKind}; use crate::scene_building::SceneBuilder; @@ -51,6 +50,10 @@ pub struct BoxShadowClipSource { // The blur shader samples BLUR_SAMPLE_SCALE * blur_radius surrounding texels. pub const BLUR_SAMPLE_SCALE: f32 = 3.0; +// Maximum blur radius for box-shadows (different than blur filters). +// Taken from nsCSSRendering.cpp in Gecko. +pub const MAX_BLUR_RADIUS: f32 = 300.; + // A cache key that uniquely identifies a minimally sized // and blurred box-shadow rect that can be stored in the // texture cache and applied to clip-masks. diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index de399e7682..2942ba2855 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -323,6 +323,7 @@ impl FrameBuilder { global_screen_world_rect, &scene.spatial_tree, global_device_pixel_scale, + (1.0, 1.0), ); surfaces.push(root_surface); diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index a7f9996a07..11e760ac47 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{ColorF, DebugCommand, DocumentId, ExternalImageData, ExternalImageId, PrimitiveFlags}; -use api::{ImageFormat, ItemTag, NotificationRequest, Shadow, FilterOp, MAX_BLUR_RADIUS}; +use api::{ImageFormat, ItemTag, NotificationRequest, Shadow, FilterOp}; use api::units::*; use api; use crate::composite::NativeSurfaceOperation; @@ -86,22 +86,6 @@ pub enum Filter { } impl Filter { - /// Ensure that the parameters for a filter operation - /// are sensible. - pub fn sanitize(&mut self) { - match self { - Filter::Blur(ref mut radius) => { - *radius = radius.min(MAX_BLUR_RADIUS); - } - Filter::DropShadows(ref mut stack) => { - for shadow in stack { - shadow.blur_radius = shadow.blur_radius.min(MAX_BLUR_RADIUS); - } - } - _ => {}, - } - } - pub fn is_visible(&self) -> bool { match *self { Filter::Identity | diff --git a/webrender/src/picture.rs b/webrender/src/picture.rs index c404ebf1fc..99cf9e76af 100644 --- a/webrender/src/picture.rs +++ b/webrender/src/picture.rs @@ -96,9 +96,9 @@ use api::{MixBlendMode, PipelineId, PremultipliedColorF, FilterPrimitiveKind}; use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode}; -use api::{DebugFlags, RasterSpace, ImageKey, ColorF, ColorU, PrimitiveFlags, MAX_BLUR_RADIUS}; +use api::{DebugFlags, RasterSpace, ImageKey, ColorF, ColorU, PrimitiveFlags}; use api::units::*; -use crate::box_shadow::{BLUR_SAMPLE_SCALE}; +use crate::box_shadow::BLUR_SAMPLE_SCALE; use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId}; use crate::spatial_tree::{ROOT_SPATIAL_NODE_INDEX, SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace @@ -133,7 +133,7 @@ use smallvec::SmallVec; use std::{mem, u8, marker, u32}; use std::sync::atomic::{AtomicUsize, Ordering}; use crate::texture_cache::TextureCacheHandle; -use crate::util::{MaxRect, scale_factors, VecHelper, RectHelpers, MatrixHelpers}; +use crate::util::{MaxRect, VecHelper, RectHelpers, MatrixHelpers}; use crate::filterdata::{FilterDataHandle}; #[cfg(any(feature = "capture", feature = "replay"))] use ron; @@ -170,6 +170,10 @@ use crate::scene_building::{SliceFlags}; // used by tileview so don't use an internal_types FastHashMap use std::collections::HashMap; +// Maximum blur radius for blur filter (different than box-shadow blur). +// Taken from FilterNodeSoftware.cpp in Gecko. +pub const MAX_BLUR_RADIUS: f32 = 100.; + /// Specify whether a surface allows subpixel AA text rendering. #[derive(Debug, Clone, PartialEq)] pub enum SubpixelMode { @@ -399,6 +403,20 @@ fn clampf(value: f32, low: f32, high: f32) -> f32 { value.max(low).min(high) } +/// Clamps the blur radius depending on scale factors. +fn clamp_blur_radius(blur_radius: f32, scale_factors: (f32, f32)) -> f32 { + // Clamping must occur after scale factors are applied, but scale factors are not applied + // until later on. To clamp the blur radius, we first apply the scale factors and then clamp + // and finally revert the scale factors. + + // TODO: the clamping should be done on a per-axis basis, but WR currently only supports + // having a single value for both x and y blur. + let largest_scale_factor = f32::max(scale_factors.0, scale_factors.1); + let adjusted_blur_radius = blur_radius * largest_scale_factor; + let clamped_blur_radius = f32::min(adjusted_blur_radius, MAX_BLUR_RADIUS); + clamped_blur_radius / largest_scale_factor +} + /// An index into the prims array in a TileDescriptor. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "capture", derive(Serialize))] @@ -3764,6 +3782,8 @@ pub struct SurfaceInfo { pub inflation_factor: f32, /// The device pixel ratio specific to this surface. pub device_pixel_scale: DevicePixelScale, + /// The scale factors of the surface to raster transform. + pub scale_factors: (f32, f32), } impl SurfaceInfo { @@ -3774,6 +3794,7 @@ impl SurfaceInfo { world_rect: WorldRect, spatial_tree: &SpatialTree, device_pixel_scale: DevicePixelScale, + scale_factors: (f32, f32), ) -> Self { let map_surface_to_world = SpaceMapper::new_with_target( ROOT_SPATIAL_NODE_INDEX, @@ -3799,6 +3820,7 @@ impl SurfaceInfo { surface_spatial_node_index, inflation_factor, device_pixel_scale, + scale_factors, } } } @@ -3861,19 +3883,20 @@ pub enum PictureCompositeMode { } impl PictureCompositeMode { - pub fn inflate_picture_rect(&self, picture_rect: PictureRect, inflation_factor: f32) -> PictureRect { + pub fn inflate_picture_rect(&self, picture_rect: PictureRect, scale_factors: (f32, f32)) -> PictureRect { let mut result_rect = picture_rect; match self { PictureCompositeMode::Filter(filter) => match filter { - Filter::Blur(_) => { + Filter::Blur(blur_radius) => { + let inflation_factor = clamp_blur_radius(*blur_radius, scale_factors).ceil() * BLUR_SAMPLE_SCALE; result_rect = picture_rect.inflate(inflation_factor, inflation_factor); }, Filter::DropShadows(shadows) => { let mut max_inflation: f32 = 0.0; for shadow in shadows { - let inflation_factor = shadow.blur_radius.ceil() * BLUR_SAMPLE_SCALE; - max_inflation = max_inflation.max(inflation_factor); + max_inflation = max_inflation.max(shadow.blur_radius); } + max_inflation = clamp_blur_radius(max_inflation, scale_factors).ceil() * BLUR_SAMPLE_SCALE; result_rect = picture_rect.inflate(max_inflation, max_inflation); }, _ => {} @@ -4544,6 +4567,10 @@ impl PicturePrimitive { .surfaces[raster_config.surface_index.0] .device_pixel_scale; + let scale_factors = frame_state + .surfaces[raster_config.surface_index.0] + .scale_factors; + let (mut clipped, mut unclipped) = match get_raster_rects( pic_rect, &map_pic_to_raster, @@ -4617,15 +4644,14 @@ impl PicturePrimitive { let dep_info = match raster_config.composite_mode { PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { - let blur_std_deviation = blur_radius * device_pixel_scale.0; - let scale_factors = scale_factors(&transform); + let blur_std_deviation = clamp_blur_radius(blur_radius, scale_factors) * device_pixel_scale.0; let mut blur_std_deviation = DeviceSize::new( blur_std_deviation * scale_factors.0, blur_std_deviation * scale_factors.1 ); let mut device_rect = if self.options.inflate_if_required { let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor; - let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil(); + let inflation_factor = inflation_factor * device_pixel_scale.0; // The clipped field is the part of the picture that is visible // on screen. The unclipped field is the screen-space rect of @@ -4638,7 +4664,7 @@ impl PicturePrimitive { // We cast clipped to f32 instead of casting unclipped to i32 // because unclipped can overflow an i32. let device_rect = clipped.to_f32() - .inflate(inflation_factor, inflation_factor) + .inflate(inflation_factor * scale_factors.0, inflation_factor * scale_factors.1) .intersection(&unclipped) .unwrap(); @@ -4711,14 +4737,15 @@ impl PicturePrimitive { for shadow in shadows { // TODO(nical) presumably we should compute the clipped rect for each shadow // and compute the union of them to determine what we need to rasterize and blur? - max_std_deviation = f32::max(max_std_deviation, shadow.blur_radius * device_pixel_scale.0); + max_std_deviation = f32::max(max_std_deviation, shadow.blur_radius); } + max_std_deviation = clamp_blur_radius(max_std_deviation, scale_factors) * device_pixel_scale.0; + let max_blur_range = max_std_deviation * BLUR_SAMPLE_SCALE; - let max_blur_range = (max_std_deviation * BLUR_SAMPLE_SCALE).ceil(); // We cast clipped to f32 instead of casting unclipped to i32 // because unclipped can overflow an i32. let device_rect = clipped.to_f32() - .inflate(max_blur_range, max_blur_range) + .inflate(max_blur_range * scale_factors.0, max_blur_range * scale_factors.1) .intersection(&unclipped) .unwrap(); @@ -4731,7 +4758,10 @@ impl PicturePrimitive { device_rect.size = RenderTask::adjusted_blur_source_size( device_rect.size, - DeviceSize::new(max_std_deviation, max_std_deviation), + DeviceSize::new( + max_std_deviation * scale_factors.0, + max_std_deviation * scale_factors.1 + ), ); if let Some(scale) = adjust_scale_for_max_surface_size( @@ -4775,14 +4805,12 @@ impl PicturePrimitive { self.extra_gpu_data_handles.resize(shadows.len(), GpuCacheHandle::new()); let mut blur_render_task_id = picture_task_id; - let scale_factors = scale_factors(&transform); for shadow in shadows { - // TODO(cbrewster): We should take the scale factors into account when clamping the max - // std deviation for the blur earlier so that we don't overinflate. + let blur_radius = clamp_blur_radius(shadow.blur_radius, scale_factors) * device_pixel_scale.0; blur_render_task_id = RenderTask::new_blur( DeviceSize::new( - f32::min(shadow.blur_radius * scale_factors.0, MAX_BLUR_RADIUS) * device_pixel_scale.0, - f32::min(shadow.blur_radius * scale_factors.1, MAX_BLUR_RADIUS) * device_pixel_scale.0, + blur_radius * scale_factors.0, + blur_radius * scale_factors.1, ), picture_task_id, frame_state.render_tasks, @@ -5602,33 +5630,6 @@ impl PicturePrimitive { let parent_raster_node_index = state.current_surface().raster_spatial_node_index; let surface_spatial_node_index = self.spatial_node_index; - // This inflation factor is to be applied to all primitives within the surface. - let inflation_factor = match composite_mode { - PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { - // Only inflate if the caller hasn't already inflated - // the bounding rects for this filter. - if self.options.inflate_if_required { - // The amount of extra space needed for primitives inside - // this picture to ensure the visibility check is correct. - BLUR_SAMPLE_SCALE * blur_radius - } else { - 0.0 - } - } - PictureCompositeMode::SvgFilter(ref primitives, _) if self.options.inflate_if_required => { - let mut max = 0.0; - for primitive in primitives { - if let FilterPrimitiveKind::Blur(ref blur) = primitive.kind { - max = f32::max(max, blur.radius * BLUR_SAMPLE_SCALE); - } - } - max - } - _ => { - 0.0 - } - }; - // Filters must be applied before transforms, to do this, we can mark this picture as establishing a raster root. let has_svg_filter = if let PictureCompositeMode::SvgFilter(..) = composite_mode { true @@ -5642,17 +5643,49 @@ impl PicturePrimitive { .get_relative_transform(surface_spatial_node_index, parent_raster_node_index) .is_perspective(); + let raster_spatial_node_index = if establishes_raster_root { + surface_spatial_node_index + } else { + parent_raster_node_index + }; + + let scale_factors = frame_context + .spatial_tree + .get_relative_transform(surface_spatial_node_index, raster_spatial_node_index) + .scale_factors(); + + // This inflation factor is to be applied to all primitives within the surface. + // Only inflate if the caller hasn't already inflated the bounding rects for this filter. + let mut inflation_factor = 0.0; + if self.options.inflate_if_required { + match composite_mode { + PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { + let blur_radius = clamp_blur_radius(blur_radius, scale_factors); + // The amount of extra space needed for primitives inside + // this picture to ensure the visibility check is correct. + inflation_factor = blur_radius * BLUR_SAMPLE_SCALE; + } + PictureCompositeMode::SvgFilter(ref primitives, _) => { + let mut max = 0.0; + for primitive in primitives { + if let FilterPrimitiveKind::Blur(ref blur) = primitive.kind { + max = f32::max(max, blur.radius); + } + } + inflation_factor = clamp_blur_radius(max, scale_factors) * BLUR_SAMPLE_SCALE; + } + _ => {} + } + } + let surface = SurfaceInfo::new( surface_spatial_node_index, - if establishes_raster_root { - surface_spatial_node_index - } else { - parent_raster_node_index - }, + raster_spatial_node_index, inflation_factor, frame_context.global_screen_world_rect, &frame_context.spatial_tree, frame_context.global_device_pixel_scale, + scale_factors, ); self.raster_config = Some(RasterConfig { @@ -5786,7 +5819,7 @@ impl PicturePrimitive { // Inflate the local bounding rect if required by the filter effect. // This inflaction factor is to be applied to the surface itself. if self.options.inflate_if_required { - surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor); + surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.scale_factors); // The picture's local rect is calculated as the union of the // snapped primitive rects, which should result in a snapped diff --git a/webrender/src/prim_store/mod.rs b/webrender/src/prim_store/mod.rs index ad1e24e61a..7653193b58 100644 --- a/webrender/src/prim_store/mod.rs +++ b/webrender/src/prim_store/mod.rs @@ -2384,7 +2384,8 @@ impl PrimitiveStore { surface.device_pixel_scale, frame_context.spatial_tree, ); - surface_rect = rc.composite_mode.inflate_picture_rect(surface_rect, surface.inflation_factor); + + surface_rect = rc.composite_mode.inflate_picture_rect(surface_rect, surface.scale_factors); surface_rect = snap_pic_to_raster.snap_rect(&surface_rect); } diff --git a/webrender/src/scene_building.rs b/webrender/src/scene_building.rs index b39dd8e86a..869f7590f2 100644 --- a/webrender/src/scene_building.rs +++ b/webrender/src/scene_building.rs @@ -2567,8 +2567,7 @@ impl<'a> SceneBuilder<'a> { // blur radius is 0, the code in Picture::prepare_for_render will // detect this and mark the picture to be drawn directly into the // parent picture, which avoids an intermediate surface and blur. - let mut blur_filter = Filter::Blur(std_deviation); - blur_filter.sanitize(); + let blur_filter = Filter::Blur(std_deviation); let composite_mode = PictureCompositeMode::Filter(blur_filter); let composite_mode_key = Some(composite_mode.clone()).into(); @@ -3475,8 +3474,6 @@ impl<'a> SceneBuilder<'a> { // For each filter, create a new image with that composite mode. let mut current_filter_data_index = 0; for filter in &mut filter_ops { - filter.sanitize(); - let composite_mode = Some(match *filter { Filter::ComponentTransfer => { let filter_data = diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index 7863604ea4..3d54a37247 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -12,10 +12,6 @@ use crate::color::ColorF; use crate::image::{ColorDepth, ImageKey}; use crate::units::*; -// Maximum blur radius. -// Taken from nsCSSRendering.cpp in Gecko. -pub const MAX_BLUR_RADIUS: f32 = 300.; - // ****************************************************************** // * NOTE: some of these structs have an "IMPLICIT" comment. * // * This indicates that the BuiltDisplayList will have serialized * @@ -871,12 +867,6 @@ pub struct BlurPrimitive { pub radius: f32, } -impl BlurPrimitive { - pub fn sanitize(&mut self) { - self.radius = self.radius.min(MAX_BLUR_RADIUS); - } -} - #[repr(C)] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct OpacityPrimitive { @@ -905,12 +895,6 @@ pub struct DropShadowPrimitive { pub shadow: Shadow, } -impl DropShadowPrimitive { - pub fn sanitize(&mut self) { - self.shadow.blur_radius = self.shadow.blur_radius.min(MAX_BLUR_RADIUS); - } -} - #[repr(C)] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct ComponentTransferPrimitive { @@ -968,9 +952,7 @@ impl FilterPrimitiveKind { pub fn sanitize(&mut self) { match self { FilterPrimitiveKind::Flood(flood) => flood.sanitize(), - FilterPrimitiveKind::Blur(blur) => blur.sanitize(), FilterPrimitiveKind::Opacity(opacity) => opacity.sanitize(), - FilterPrimitiveKind::DropShadow(drop_shadow) => drop_shadow.sanitize(), // No sanitization needed. FilterPrimitiveKind::Identity(..) | @@ -978,6 +960,8 @@ impl FilterPrimitiveKind { FilterPrimitiveKind::ColorMatrix(..) | FilterPrimitiveKind::Offset(..) | FilterPrimitiveKind::Composite(..) | + FilterPrimitiveKind::Blur(..) | + FilterPrimitiveKind::DropShadow(..) | // Component transfer's filter data is sanitized separately. FilterPrimitiveKind::ComponentTransfer(..) => {} } diff --git a/wrench/reftests/filters/filter-blur-clamping-ref.yaml b/wrench/reftests/filters/filter-blur-clamping-ref.yaml new file mode 100644 index 0000000000..cdc6c56a47 --- /dev/null +++ b/wrench/reftests/filters/filter-blur-clamping-ref.yaml @@ -0,0 +1,18 @@ +# Ensures that blur clamping happens after scale factors are applied +--- +root: + items: + - type: stacking-context + bounds: [100, 100, 300, 300] + filters: blur(100) + items: + - type: rect + bounds: [0, 0, 100, 100] + color: 0 255 0 1.0 + - type: stacking-context + bounds: [400, 100, 300, 300] + filters: blur(50) + items: + - type: rect + bounds: [0, 0, 100, 100] + color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-blur-clamping.yaml b/wrench/reftests/filters/filter-blur-clamping.yaml new file mode 100644 index 0000000000..614aa8ee02 --- /dev/null +++ b/wrench/reftests/filters/filter-blur-clamping.yaml @@ -0,0 +1,30 @@ +# Ensures that blur clamping happens after scale factors are applied +--- +root: + items: + - type: stacking-context + bounds: [100, 100, 300, 300] + transform: scale(10) + items: + - type: stacking-context + bounds: [0, 0, 300, 300] + # Blur will be 20 * 10(scale) = 200 and it should then be clamped to 100 + filters: blur(20) + items: + - type: rect + bounds: [0, 0, 10, 10] + color: 0 255 0 1.0 + - type: stacking-context + bounds: [400, 100, 300, 300] + transform: scale(0.1) + items: + - type: stacking-context + bounds: [0, 0, 300, 300] + # Blur should be 500 * 0.1(scale) = 50. This tests to make sure clamping + # does not occur before applying scale factors, otherwise 500 would be + # clamped to 100. + filters: blur(500) + items: + - type: rect + bounds: [0, 0, 1000, 1000] + color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml b/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml new file mode 100644 index 0000000000..6ffcde5f5b --- /dev/null +++ b/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml @@ -0,0 +1,18 @@ +# Ensures that blur clamping happens after scale factors are applied +--- +root: + items: + - type: stacking-context + bounds: [100, 100, 300, 300] + filters: drop-shadow([0, 0], 100, blue) + items: + - type: rect + bounds: [0, 0, 100, 100] + color: 0 255 0 1.0 + - type: stacking-context + bounds: [400, 100, 300, 300] + filters: drop-shadow([0, 0], 50, green) + items: + - type: rect + bounds: [0, 0, 100, 100] + color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml b/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml new file mode 100644 index 0000000000..1d7157a8e6 --- /dev/null +++ b/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml @@ -0,0 +1,30 @@ +# Ensures that blur clamping happens after scale factors are applied +--- +root: + items: + - type: stacking-context + bounds: [100, 100, 300, 300] + transform: scale(10) + items: + - type: stacking-context + bounds: [0, 0, 300, 300] + # Blur will be 20 * 10(scale) = 200 and it should then be clamped to 100 + filters: drop-shadow([0, 0], 20, blue) + items: + - type: rect + bounds: [0, 0, 10, 10] + color: 0 255 0 1.0 + - type: stacking-context + bounds: [400, 100, 300, 300] + transform: scale(0.1) + items: + - type: stacking-context + bounds: [0, 0, 300, 300] + # Blur should be 500 * 0.1(scale) = 50. This tests to make sure clamping + # does not occur before applying scale factors, otherwise 500 would be + # clamped to 100. + filters: drop-shadow([0, 0], 500, green) + items: + - type: rect + bounds: [0, 0, 1000, 1000] + color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml b/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml index 65c699f8fa..e46af9dfa4 100644 --- a/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml +++ b/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml @@ -7,11 +7,11 @@ root: items: - type: stacking-context bounds: [0, 0, 1000, 1000] - transform: scale-y(999999.25) + transform: scale-y(100) items: - type: stacking-context bounds: [0, 0, 1000, 1000] - filters: drop-shadow([999999, 999999], 999999, [255, 0, 0, 1]) + filters: drop-shadow([0, 0], 999999, [255, 0, 0, 1]) items: - image: checkerboard(2, 16, 16) bounds: [0, 0, 1000, 1000] diff --git a/wrench/reftests/filters/reftest.list b/wrench/reftests/filters/reftest.list index 7222c7b5c4..0853d8fbc7 100644 --- a/wrench/reftests/filters/reftest.list +++ b/wrench/reftests/filters/reftest.list @@ -45,7 +45,9 @@ skip_on(android,device) == filter-mix-blend-mode.yaml filter-mix-blend-mode-ref. != filter-blur-huge.yaml blank.yaml != filter-drop-shadow-huge.yaml blank.yaml != filter-drop-shadow-transform-huge.yaml blank.yaml +== filter-drop-shadow-blur-clamping.yaml filter-drop-shadow-blur-clamping-ref.yaml == filter-blur-scaled.yaml filter-blur-scaled-ref.yaml +== filter-blur-clamping.yaml filter-blur-clamping-ref.yaml skip_on(android,device) fuzzy(1,104) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Pixel2 == svg-filter-component-transfer.yaml filter-component-transfer-ref.yaml == svg-filter-flood.yaml svg-filter-flood-ref.yaml From 1b3dde78a99b9792bcc78a090305dd74a165d7ab Mon Sep 17 00:00:00 2001 From: Razvan Maries Date: Tue, 24 Mar 2020 03:10:26 +0000 Subject: [PATCH 2/4] Backed out 2 changesets (bug 1618000) for wrench bustages. CLOSED TREE Backed out changeset c72b18b22267 (bug 1618000) Backed out changeset 9bc71e7b317b (bug 1618000) [ghsync] From https://hg.mozilla.org/mozilla-central/rev/fc4c4e983d42d9bf0600385276e6e23c22a7eaa9 --- webrender/src/box_shadow.rs | 5 +- webrender/src/frame_builder.rs | 1 - webrender/src/internal_types.rs | 18 ++- webrender/src/picture.rs | 139 +++++++----------- webrender/src/prim_store/mod.rs | 3 +- webrender/src/scene_building.rs | 5 +- webrender_api/src/display_item.rs | 20 ++- .../filters/filter-blur-clamping-ref.yaml | 18 --- .../filters/filter-blur-clamping.yaml | 30 ---- .../filter-drop-shadow-blur-clamping-ref.yaml | 18 --- .../filter-drop-shadow-blur-clamping.yaml | 30 ---- .../filter-drop-shadow-transform-huge.yaml | 4 +- wrench/reftests/filters/reftest.list | 2 - 13 files changed, 96 insertions(+), 197 deletions(-) delete mode 100644 wrench/reftests/filters/filter-blur-clamping-ref.yaml delete mode 100644 wrench/reftests/filters/filter-blur-clamping.yaml delete mode 100644 wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml delete mode 100644 wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml diff --git a/webrender/src/box_shadow.rs b/webrender/src/box_shadow.rs index c2ef077e81..eb8d4d0d4e 100644 --- a/webrender/src/box_shadow.rs +++ b/webrender/src/box_shadow.rs @@ -4,6 +4,7 @@ use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, PrimitiveKeyKind}; use api::PropertyBinding; +use api::MAX_BLUR_RADIUS; use api::units::*; use crate::clip::{ClipItemKey, ClipItemKeyKind}; use crate::scene_building::SceneBuilder; @@ -50,10 +51,6 @@ pub struct BoxShadowClipSource { // The blur shader samples BLUR_SAMPLE_SCALE * blur_radius surrounding texels. pub const BLUR_SAMPLE_SCALE: f32 = 3.0; -// Maximum blur radius for box-shadows (different than blur filters). -// Taken from nsCSSRendering.cpp in Gecko. -pub const MAX_BLUR_RADIUS: f32 = 300.; - // A cache key that uniquely identifies a minimally sized // and blurred box-shadow rect that can be stored in the // texture cache and applied to clip-masks. diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 2942ba2855..de399e7682 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -323,7 +323,6 @@ impl FrameBuilder { global_screen_world_rect, &scene.spatial_tree, global_device_pixel_scale, - (1.0, 1.0), ); surfaces.push(root_surface); diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index 11e760ac47..a7f9996a07 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{ColorF, DebugCommand, DocumentId, ExternalImageData, ExternalImageId, PrimitiveFlags}; -use api::{ImageFormat, ItemTag, NotificationRequest, Shadow, FilterOp}; +use api::{ImageFormat, ItemTag, NotificationRequest, Shadow, FilterOp, MAX_BLUR_RADIUS}; use api::units::*; use api; use crate::composite::NativeSurfaceOperation; @@ -86,6 +86,22 @@ pub enum Filter { } impl Filter { + /// Ensure that the parameters for a filter operation + /// are sensible. + pub fn sanitize(&mut self) { + match self { + Filter::Blur(ref mut radius) => { + *radius = radius.min(MAX_BLUR_RADIUS); + } + Filter::DropShadows(ref mut stack) => { + for shadow in stack { + shadow.blur_radius = shadow.blur_radius.min(MAX_BLUR_RADIUS); + } + } + _ => {}, + } + } + pub fn is_visible(&self) -> bool { match *self { Filter::Identity | diff --git a/webrender/src/picture.rs b/webrender/src/picture.rs index 99cf9e76af..c404ebf1fc 100644 --- a/webrender/src/picture.rs +++ b/webrender/src/picture.rs @@ -96,9 +96,9 @@ use api::{MixBlendMode, PipelineId, PremultipliedColorF, FilterPrimitiveKind}; use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode}; -use api::{DebugFlags, RasterSpace, ImageKey, ColorF, ColorU, PrimitiveFlags}; +use api::{DebugFlags, RasterSpace, ImageKey, ColorF, ColorU, PrimitiveFlags, MAX_BLUR_RADIUS}; use api::units::*; -use crate::box_shadow::BLUR_SAMPLE_SCALE; +use crate::box_shadow::{BLUR_SAMPLE_SCALE}; use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId}; use crate::spatial_tree::{ROOT_SPATIAL_NODE_INDEX, SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace @@ -133,7 +133,7 @@ use smallvec::SmallVec; use std::{mem, u8, marker, u32}; use std::sync::atomic::{AtomicUsize, Ordering}; use crate::texture_cache::TextureCacheHandle; -use crate::util::{MaxRect, VecHelper, RectHelpers, MatrixHelpers}; +use crate::util::{MaxRect, scale_factors, VecHelper, RectHelpers, MatrixHelpers}; use crate::filterdata::{FilterDataHandle}; #[cfg(any(feature = "capture", feature = "replay"))] use ron; @@ -170,10 +170,6 @@ use crate::scene_building::{SliceFlags}; // used by tileview so don't use an internal_types FastHashMap use std::collections::HashMap; -// Maximum blur radius for blur filter (different than box-shadow blur). -// Taken from FilterNodeSoftware.cpp in Gecko. -pub const MAX_BLUR_RADIUS: f32 = 100.; - /// Specify whether a surface allows subpixel AA text rendering. #[derive(Debug, Clone, PartialEq)] pub enum SubpixelMode { @@ -403,20 +399,6 @@ fn clampf(value: f32, low: f32, high: f32) -> f32 { value.max(low).min(high) } -/// Clamps the blur radius depending on scale factors. -fn clamp_blur_radius(blur_radius: f32, scale_factors: (f32, f32)) -> f32 { - // Clamping must occur after scale factors are applied, but scale factors are not applied - // until later on. To clamp the blur radius, we first apply the scale factors and then clamp - // and finally revert the scale factors. - - // TODO: the clamping should be done on a per-axis basis, but WR currently only supports - // having a single value for both x and y blur. - let largest_scale_factor = f32::max(scale_factors.0, scale_factors.1); - let adjusted_blur_radius = blur_radius * largest_scale_factor; - let clamped_blur_radius = f32::min(adjusted_blur_radius, MAX_BLUR_RADIUS); - clamped_blur_radius / largest_scale_factor -} - /// An index into the prims array in a TileDescriptor. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "capture", derive(Serialize))] @@ -3782,8 +3764,6 @@ pub struct SurfaceInfo { pub inflation_factor: f32, /// The device pixel ratio specific to this surface. pub device_pixel_scale: DevicePixelScale, - /// The scale factors of the surface to raster transform. - pub scale_factors: (f32, f32), } impl SurfaceInfo { @@ -3794,7 +3774,6 @@ impl SurfaceInfo { world_rect: WorldRect, spatial_tree: &SpatialTree, device_pixel_scale: DevicePixelScale, - scale_factors: (f32, f32), ) -> Self { let map_surface_to_world = SpaceMapper::new_with_target( ROOT_SPATIAL_NODE_INDEX, @@ -3820,7 +3799,6 @@ impl SurfaceInfo { surface_spatial_node_index, inflation_factor, device_pixel_scale, - scale_factors, } } } @@ -3883,20 +3861,19 @@ pub enum PictureCompositeMode { } impl PictureCompositeMode { - pub fn inflate_picture_rect(&self, picture_rect: PictureRect, scale_factors: (f32, f32)) -> PictureRect { + pub fn inflate_picture_rect(&self, picture_rect: PictureRect, inflation_factor: f32) -> PictureRect { let mut result_rect = picture_rect; match self { PictureCompositeMode::Filter(filter) => match filter { - Filter::Blur(blur_radius) => { - let inflation_factor = clamp_blur_radius(*blur_radius, scale_factors).ceil() * BLUR_SAMPLE_SCALE; + Filter::Blur(_) => { result_rect = picture_rect.inflate(inflation_factor, inflation_factor); }, Filter::DropShadows(shadows) => { let mut max_inflation: f32 = 0.0; for shadow in shadows { - max_inflation = max_inflation.max(shadow.blur_radius); + let inflation_factor = shadow.blur_radius.ceil() * BLUR_SAMPLE_SCALE; + max_inflation = max_inflation.max(inflation_factor); } - max_inflation = clamp_blur_radius(max_inflation, scale_factors).ceil() * BLUR_SAMPLE_SCALE; result_rect = picture_rect.inflate(max_inflation, max_inflation); }, _ => {} @@ -4567,10 +4544,6 @@ impl PicturePrimitive { .surfaces[raster_config.surface_index.0] .device_pixel_scale; - let scale_factors = frame_state - .surfaces[raster_config.surface_index.0] - .scale_factors; - let (mut clipped, mut unclipped) = match get_raster_rects( pic_rect, &map_pic_to_raster, @@ -4644,14 +4617,15 @@ impl PicturePrimitive { let dep_info = match raster_config.composite_mode { PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { - let blur_std_deviation = clamp_blur_radius(blur_radius, scale_factors) * device_pixel_scale.0; + let blur_std_deviation = blur_radius * device_pixel_scale.0; + let scale_factors = scale_factors(&transform); let mut blur_std_deviation = DeviceSize::new( blur_std_deviation * scale_factors.0, blur_std_deviation * scale_factors.1 ); let mut device_rect = if self.options.inflate_if_required { let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor; - let inflation_factor = inflation_factor * device_pixel_scale.0; + let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil(); // The clipped field is the part of the picture that is visible // on screen. The unclipped field is the screen-space rect of @@ -4664,7 +4638,7 @@ impl PicturePrimitive { // We cast clipped to f32 instead of casting unclipped to i32 // because unclipped can overflow an i32. let device_rect = clipped.to_f32() - .inflate(inflation_factor * scale_factors.0, inflation_factor * scale_factors.1) + .inflate(inflation_factor, inflation_factor) .intersection(&unclipped) .unwrap(); @@ -4737,15 +4711,14 @@ impl PicturePrimitive { for shadow in shadows { // TODO(nical) presumably we should compute the clipped rect for each shadow // and compute the union of them to determine what we need to rasterize and blur? - max_std_deviation = f32::max(max_std_deviation, shadow.blur_radius); + max_std_deviation = f32::max(max_std_deviation, shadow.blur_radius * device_pixel_scale.0); } - max_std_deviation = clamp_blur_radius(max_std_deviation, scale_factors) * device_pixel_scale.0; - let max_blur_range = max_std_deviation * BLUR_SAMPLE_SCALE; + let max_blur_range = (max_std_deviation * BLUR_SAMPLE_SCALE).ceil(); // We cast clipped to f32 instead of casting unclipped to i32 // because unclipped can overflow an i32. let device_rect = clipped.to_f32() - .inflate(max_blur_range * scale_factors.0, max_blur_range * scale_factors.1) + .inflate(max_blur_range, max_blur_range) .intersection(&unclipped) .unwrap(); @@ -4758,10 +4731,7 @@ impl PicturePrimitive { device_rect.size = RenderTask::adjusted_blur_source_size( device_rect.size, - DeviceSize::new( - max_std_deviation * scale_factors.0, - max_std_deviation * scale_factors.1 - ), + DeviceSize::new(max_std_deviation, max_std_deviation), ); if let Some(scale) = adjust_scale_for_max_surface_size( @@ -4805,12 +4775,14 @@ impl PicturePrimitive { self.extra_gpu_data_handles.resize(shadows.len(), GpuCacheHandle::new()); let mut blur_render_task_id = picture_task_id; + let scale_factors = scale_factors(&transform); for shadow in shadows { - let blur_radius = clamp_blur_radius(shadow.blur_radius, scale_factors) * device_pixel_scale.0; + // TODO(cbrewster): We should take the scale factors into account when clamping the max + // std deviation for the blur earlier so that we don't overinflate. blur_render_task_id = RenderTask::new_blur( DeviceSize::new( - blur_radius * scale_factors.0, - blur_radius * scale_factors.1, + f32::min(shadow.blur_radius * scale_factors.0, MAX_BLUR_RADIUS) * device_pixel_scale.0, + f32::min(shadow.blur_radius * scale_factors.1, MAX_BLUR_RADIUS) * device_pixel_scale.0, ), picture_task_id, frame_state.render_tasks, @@ -5630,6 +5602,33 @@ impl PicturePrimitive { let parent_raster_node_index = state.current_surface().raster_spatial_node_index; let surface_spatial_node_index = self.spatial_node_index; + // This inflation factor is to be applied to all primitives within the surface. + let inflation_factor = match composite_mode { + PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { + // Only inflate if the caller hasn't already inflated + // the bounding rects for this filter. + if self.options.inflate_if_required { + // The amount of extra space needed for primitives inside + // this picture to ensure the visibility check is correct. + BLUR_SAMPLE_SCALE * blur_radius + } else { + 0.0 + } + } + PictureCompositeMode::SvgFilter(ref primitives, _) if self.options.inflate_if_required => { + let mut max = 0.0; + for primitive in primitives { + if let FilterPrimitiveKind::Blur(ref blur) = primitive.kind { + max = f32::max(max, blur.radius * BLUR_SAMPLE_SCALE); + } + } + max + } + _ => { + 0.0 + } + }; + // Filters must be applied before transforms, to do this, we can mark this picture as establishing a raster root. let has_svg_filter = if let PictureCompositeMode::SvgFilter(..) = composite_mode { true @@ -5643,49 +5642,17 @@ impl PicturePrimitive { .get_relative_transform(surface_spatial_node_index, parent_raster_node_index) .is_perspective(); - let raster_spatial_node_index = if establishes_raster_root { - surface_spatial_node_index - } else { - parent_raster_node_index - }; - - let scale_factors = frame_context - .spatial_tree - .get_relative_transform(surface_spatial_node_index, raster_spatial_node_index) - .scale_factors(); - - // This inflation factor is to be applied to all primitives within the surface. - // Only inflate if the caller hasn't already inflated the bounding rects for this filter. - let mut inflation_factor = 0.0; - if self.options.inflate_if_required { - match composite_mode { - PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => { - let blur_radius = clamp_blur_radius(blur_radius, scale_factors); - // The amount of extra space needed for primitives inside - // this picture to ensure the visibility check is correct. - inflation_factor = blur_radius * BLUR_SAMPLE_SCALE; - } - PictureCompositeMode::SvgFilter(ref primitives, _) => { - let mut max = 0.0; - for primitive in primitives { - if let FilterPrimitiveKind::Blur(ref blur) = primitive.kind { - max = f32::max(max, blur.radius); - } - } - inflation_factor = clamp_blur_radius(max, scale_factors) * BLUR_SAMPLE_SCALE; - } - _ => {} - } - } - let surface = SurfaceInfo::new( surface_spatial_node_index, - raster_spatial_node_index, + if establishes_raster_root { + surface_spatial_node_index + } else { + parent_raster_node_index + }, inflation_factor, frame_context.global_screen_world_rect, &frame_context.spatial_tree, frame_context.global_device_pixel_scale, - scale_factors, ); self.raster_config = Some(RasterConfig { @@ -5819,7 +5786,7 @@ impl PicturePrimitive { // Inflate the local bounding rect if required by the filter effect. // This inflaction factor is to be applied to the surface itself. if self.options.inflate_if_required { - surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.scale_factors); + surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor); // The picture's local rect is calculated as the union of the // snapped primitive rects, which should result in a snapped diff --git a/webrender/src/prim_store/mod.rs b/webrender/src/prim_store/mod.rs index 7653193b58..ad1e24e61a 100644 --- a/webrender/src/prim_store/mod.rs +++ b/webrender/src/prim_store/mod.rs @@ -2384,8 +2384,7 @@ impl PrimitiveStore { surface.device_pixel_scale, frame_context.spatial_tree, ); - - surface_rect = rc.composite_mode.inflate_picture_rect(surface_rect, surface.scale_factors); + surface_rect = rc.composite_mode.inflate_picture_rect(surface_rect, surface.inflation_factor); surface_rect = snap_pic_to_raster.snap_rect(&surface_rect); } diff --git a/webrender/src/scene_building.rs b/webrender/src/scene_building.rs index 869f7590f2..b39dd8e86a 100644 --- a/webrender/src/scene_building.rs +++ b/webrender/src/scene_building.rs @@ -2567,7 +2567,8 @@ impl<'a> SceneBuilder<'a> { // blur radius is 0, the code in Picture::prepare_for_render will // detect this and mark the picture to be drawn directly into the // parent picture, which avoids an intermediate surface and blur. - let blur_filter = Filter::Blur(std_deviation); + let mut blur_filter = Filter::Blur(std_deviation); + blur_filter.sanitize(); let composite_mode = PictureCompositeMode::Filter(blur_filter); let composite_mode_key = Some(composite_mode.clone()).into(); @@ -3474,6 +3475,8 @@ impl<'a> SceneBuilder<'a> { // For each filter, create a new image with that composite mode. let mut current_filter_data_index = 0; for filter in &mut filter_ops { + filter.sanitize(); + let composite_mode = Some(match *filter { Filter::ComponentTransfer => { let filter_data = diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index 3d54a37247..7863604ea4 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -12,6 +12,10 @@ use crate::color::ColorF; use crate::image::{ColorDepth, ImageKey}; use crate::units::*; +// Maximum blur radius. +// Taken from nsCSSRendering.cpp in Gecko. +pub const MAX_BLUR_RADIUS: f32 = 300.; + // ****************************************************************** // * NOTE: some of these structs have an "IMPLICIT" comment. * // * This indicates that the BuiltDisplayList will have serialized * @@ -867,6 +871,12 @@ pub struct BlurPrimitive { pub radius: f32, } +impl BlurPrimitive { + pub fn sanitize(&mut self) { + self.radius = self.radius.min(MAX_BLUR_RADIUS); + } +} + #[repr(C)] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct OpacityPrimitive { @@ -895,6 +905,12 @@ pub struct DropShadowPrimitive { pub shadow: Shadow, } +impl DropShadowPrimitive { + pub fn sanitize(&mut self) { + self.shadow.blur_radius = self.shadow.blur_radius.min(MAX_BLUR_RADIUS); + } +} + #[repr(C)] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct ComponentTransferPrimitive { @@ -952,7 +968,9 @@ impl FilterPrimitiveKind { pub fn sanitize(&mut self) { match self { FilterPrimitiveKind::Flood(flood) => flood.sanitize(), + FilterPrimitiveKind::Blur(blur) => blur.sanitize(), FilterPrimitiveKind::Opacity(opacity) => opacity.sanitize(), + FilterPrimitiveKind::DropShadow(drop_shadow) => drop_shadow.sanitize(), // No sanitization needed. FilterPrimitiveKind::Identity(..) | @@ -960,8 +978,6 @@ impl FilterPrimitiveKind { FilterPrimitiveKind::ColorMatrix(..) | FilterPrimitiveKind::Offset(..) | FilterPrimitiveKind::Composite(..) | - FilterPrimitiveKind::Blur(..) | - FilterPrimitiveKind::DropShadow(..) | // Component transfer's filter data is sanitized separately. FilterPrimitiveKind::ComponentTransfer(..) => {} } diff --git a/wrench/reftests/filters/filter-blur-clamping-ref.yaml b/wrench/reftests/filters/filter-blur-clamping-ref.yaml deleted file mode 100644 index cdc6c56a47..0000000000 --- a/wrench/reftests/filters/filter-blur-clamping-ref.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Ensures that blur clamping happens after scale factors are applied ---- -root: - items: - - type: stacking-context - bounds: [100, 100, 300, 300] - filters: blur(100) - items: - - type: rect - bounds: [0, 0, 100, 100] - color: 0 255 0 1.0 - - type: stacking-context - bounds: [400, 100, 300, 300] - filters: blur(50) - items: - - type: rect - bounds: [0, 0, 100, 100] - color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-blur-clamping.yaml b/wrench/reftests/filters/filter-blur-clamping.yaml deleted file mode 100644 index 614aa8ee02..0000000000 --- a/wrench/reftests/filters/filter-blur-clamping.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Ensures that blur clamping happens after scale factors are applied ---- -root: - items: - - type: stacking-context - bounds: [100, 100, 300, 300] - transform: scale(10) - items: - - type: stacking-context - bounds: [0, 0, 300, 300] - # Blur will be 20 * 10(scale) = 200 and it should then be clamped to 100 - filters: blur(20) - items: - - type: rect - bounds: [0, 0, 10, 10] - color: 0 255 0 1.0 - - type: stacking-context - bounds: [400, 100, 300, 300] - transform: scale(0.1) - items: - - type: stacking-context - bounds: [0, 0, 300, 300] - # Blur should be 500 * 0.1(scale) = 50. This tests to make sure clamping - # does not occur before applying scale factors, otherwise 500 would be - # clamped to 100. - filters: blur(500) - items: - - type: rect - bounds: [0, 0, 1000, 1000] - color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml b/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml deleted file mode 100644 index 6ffcde5f5b..0000000000 --- a/wrench/reftests/filters/filter-drop-shadow-blur-clamping-ref.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Ensures that blur clamping happens after scale factors are applied ---- -root: - items: - - type: stacking-context - bounds: [100, 100, 300, 300] - filters: drop-shadow([0, 0], 100, blue) - items: - - type: rect - bounds: [0, 0, 100, 100] - color: 0 255 0 1.0 - - type: stacking-context - bounds: [400, 100, 300, 300] - filters: drop-shadow([0, 0], 50, green) - items: - - type: rect - bounds: [0, 0, 100, 100] - color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml b/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml deleted file mode 100644 index 1d7157a8e6..0000000000 --- a/wrench/reftests/filters/filter-drop-shadow-blur-clamping.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Ensures that blur clamping happens after scale factors are applied ---- -root: - items: - - type: stacking-context - bounds: [100, 100, 300, 300] - transform: scale(10) - items: - - type: stacking-context - bounds: [0, 0, 300, 300] - # Blur will be 20 * 10(scale) = 200 and it should then be clamped to 100 - filters: drop-shadow([0, 0], 20, blue) - items: - - type: rect - bounds: [0, 0, 10, 10] - color: 0 255 0 1.0 - - type: stacking-context - bounds: [400, 100, 300, 300] - transform: scale(0.1) - items: - - type: stacking-context - bounds: [0, 0, 300, 300] - # Blur should be 500 * 0.1(scale) = 50. This tests to make sure clamping - # does not occur before applying scale factors, otherwise 500 would be - # clamped to 100. - filters: drop-shadow([0, 0], 500, green) - items: - - type: rect - bounds: [0, 0, 1000, 1000] - color: 255 0 0 1.0 diff --git a/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml b/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml index e46af9dfa4..65c699f8fa 100644 --- a/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml +++ b/wrench/reftests/filters/filter-drop-shadow-transform-huge.yaml @@ -7,11 +7,11 @@ root: items: - type: stacking-context bounds: [0, 0, 1000, 1000] - transform: scale-y(100) + transform: scale-y(999999.25) items: - type: stacking-context bounds: [0, 0, 1000, 1000] - filters: drop-shadow([0, 0], 999999, [255, 0, 0, 1]) + filters: drop-shadow([999999, 999999], 999999, [255, 0, 0, 1]) items: - image: checkerboard(2, 16, 16) bounds: [0, 0, 1000, 1000] diff --git a/wrench/reftests/filters/reftest.list b/wrench/reftests/filters/reftest.list index 0853d8fbc7..7222c7b5c4 100644 --- a/wrench/reftests/filters/reftest.list +++ b/wrench/reftests/filters/reftest.list @@ -45,9 +45,7 @@ skip_on(android,device) == filter-mix-blend-mode.yaml filter-mix-blend-mode-ref. != filter-blur-huge.yaml blank.yaml != filter-drop-shadow-huge.yaml blank.yaml != filter-drop-shadow-transform-huge.yaml blank.yaml -== filter-drop-shadow-blur-clamping.yaml filter-drop-shadow-blur-clamping-ref.yaml == filter-blur-scaled.yaml filter-blur-scaled-ref.yaml -== filter-blur-clamping.yaml filter-blur-clamping-ref.yaml skip_on(android,device) fuzzy(1,104) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Pixel2 == svg-filter-component-transfer.yaml filter-component-transfer-ref.yaml == svg-filter-flood.yaml svg-filter-flood-ref.yaml From 1ca61d55913ebb735594e4a9378c0d3470a1adc4 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 24 Mar 2020 03:10:35 +0000 Subject: [PATCH 3/4] Bug 1623791 - Remove segment gridding optimization. r=nical This is no longer as important, with picture caching. Removing it will simplify the planned changes to switch to a simpler segment model based on nine-patch rectangles during scene building. Differential Revision: https://phabricator.services.mozilla.com/D67792 [ghsync] From https://hg.mozilla.org/mozilla-central/rev/5d5fee77d845a14efd3bb4f3988c5ecb1abbae80 --- webrender/src/prim_store/mod.rs | 62 ++---------------- .../boxshadow/box-shadow-border-radii.png | Bin 12350 -> 12336 bytes wrench/reftests/text/perspective-clip.png | Bin 1762 -> 1753 bytes .../transforms/perspective-border-radius.png | Bin 18227 -> 11839 bytes .../transforms/perspective-shadow.png | Bin 10536 -> 10342 bytes wrench/reftests/transforms/prim-suite.png | Bin 48510 -> 48506 bytes wrench/reftests/transforms/reftest.list | 2 +- .../transforms/rotated-clip-large.png | Bin 7433 -> 7424 bytes 8 files changed, 8 insertions(+), 56 deletions(-) diff --git a/webrender/src/prim_store/mod.rs b/webrender/src/prim_store/mod.rs index ad1e24e61a..1430614080 100644 --- a/webrender/src/prim_store/mod.rs +++ b/webrender/src/prim_store/mod.rs @@ -82,7 +82,7 @@ pub fn register_prim_chase_id(id: PrimitiveDebugId) { pub fn register_prim_chase_id(_: PrimitiveDebugId) { } -const MIN_BRUSH_SPLIT_AREA: f32 = 256.0 * 256.0; +const MIN_BRUSH_SPLIT_AREA: f32 = 128.0 * 128.0; pub const VECS_PER_SEGMENT: usize = 2; #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)] @@ -3696,17 +3696,11 @@ impl<'a> GpuDataRequest<'a> { clip_store: &ClipStore, data_stores: &DataStores, ) -> bool { - // If the brush is small, we generally want to skip building segments - // and just draw it as a single primitive with clip mask. However, - // if the clips are purely rectangles that have no per-fragment - // clip masks, we will segment anyway. This allows us to completely - // skip allocating a clip mask in these cases. - let is_large = prim_local_rect.size.area() > MIN_BRUSH_SPLIT_AREA; - - // TODO(gw): We should probably detect and store this on each - // ClipSources instance, to avoid having to iterate - // the clip sources here. - let mut rect_clips_only = true; + // If the brush is small, we want to skip building segments + // and just draw it as a single primitive with clip mask. + if prim_local_rect.size.area() < MIN_BRUSH_SPLIT_AREA { + return false; + } segment_builder.initialize( prim_local_rect, @@ -3715,7 +3709,6 @@ impl<'a> GpuDataRequest<'a> { ); // Segment the primitive on all the local-space clip sources that we can. - let mut local_clip_count = 0; for i in 0 .. clip_chain.clips_range.count { let clip_instance = clip_store .get_instance_from_range(&clip_chain.clips_range, i); @@ -3730,19 +3723,14 @@ impl<'a> GpuDataRequest<'a> { continue; } - local_clip_count += 1; - let (local_clip_rect, radius, mode) = match clip_node.item.kind { ClipItemKind::RoundedRectangle { rect, radius, mode } => { - rect_clips_only = false; (rect, Some(radius), mode) } ClipItemKind::Rectangle { rect, mode } => { (rect, None, mode) } ClipItemKind::BoxShadow { ref source } => { - rect_clips_only = false; - // For inset box shadows, we can clip out any // pixels that are inside the shadow region // and are beyond the inner rect, as they can't @@ -3781,43 +3769,7 @@ impl<'a> GpuDataRequest<'a> { segment_builder.push_clip_rect(local_clip_rect, radius, mode); } - if is_large || rect_clips_only { - // If there were no local clips, then we will subdivide the primitive into - // a uniform grid (up to 8x8 segments). This will typically result in - // a significant number of those segments either being completely clipped, - // or determined to not need a clip mask for that segment. - if local_clip_count == 0 && clip_chain.clips_range.count > 0 { - let x_clip_count = cmp::min(8, (prim_local_rect.size.width / 128.0).ceil() as i32); - let y_clip_count = cmp::min(8, (prim_local_rect.size.height / 128.0).ceil() as i32); - - for y in 0 .. y_clip_count { - let y0 = prim_local_rect.size.height * y as f32 / y_clip_count as f32; - let y1 = prim_local_rect.size.height * (y+1) as f32 / y_clip_count as f32; - - for x in 0 .. x_clip_count { - let x0 = prim_local_rect.size.width * x as f32 / x_clip_count as f32; - let x1 = prim_local_rect.size.width * (x+1) as f32 / x_clip_count as f32; - - let rect = LayoutRect::new( - LayoutPoint::new( - x0 + prim_local_rect.origin.x, - y0 + prim_local_rect.origin.y, - ), - LayoutSize::new( - x1 - x0, - y1 - y0, - ), - ); - - segment_builder.push_mask_region(rect, LayoutRect::zero(), None); - } - } - } - - return true - } - - false + true } impl PrimitiveInstance { diff --git a/wrench/reftests/boxshadow/box-shadow-border-radii.png b/wrench/reftests/boxshadow/box-shadow-border-radii.png index 3fe9d3c06c5fd0c7646f450ee4e6f2a3bb08b483..6143955683ee47cbac1e0c7d0a49d37499e826fe 100644 GIT binary patch literal 12336 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 o@(Q0_=g}J5|DOiU4^OmSQ;mDyeJ&IHPkOTg zVh}3(UJSC=*s{OZ^gQ49IDW_b&-?fL{*ik?)#*^SvKQ13c)sHw*Pn2M@Tr;bUsxfmnWIy(@Td(ey|V7~k#jgog=U z=MSEhVEmrI;s5Cg!rN%OVja$@@%w5>-*dObYO6CZhRi|7*A|y+7u3qVmDaIiY8~7Y z`YFE8i0XBoxB8u1KF&gzVdK-3_5dtCeNaQFPG#KRs#|S8C#>()GS2q1DJ!A2nHgA|nE>swCO$=c zQgq4+PcJ0?DDfvWUNr^_btt~Dj!}o(b81RU_=gQ$x4x3#Pe6Twu>NdtPEe(3qa-kr0>uA+j!3CG;Mhm)TgDZ-Un&5X`Rfub-;LrYo_!rTaC1d92=y&sy{B?zv;3#K3q{TMf zx-4#OVZM$ntMcPdwxGuNAsIB)OltT0h)j-I-^+Y3hjG|t8$=q%F0;MM|5bj;O3=&Z zR~j9B0vUxmj%O@NUHUb1iV@E!W{0WqL$Mv-og_ZQk>_TvBaDx?PgeNa!cm_t9Mp8y zTn%IXr27}YTxcLWoy4Qp5{Vxh+Gflt z#WFgliNxp^mX{LVIMS(-^Pf}Orh*^O&jLYu-(5Ts)VQ;%J>h?z&rLJoc#A+_N%vq7KP3~lrLZtR^dbE@x8Eh@j`xhAh%+WvM8W>XxOMPIy} zJoS_MXX!glLgzIFd|peq8&MpgtB13(G#=+{;bTN;5BZ~c(~g}#cXbLkI%DJ&Ibs*J zdPA1@Rr{SkamV-;0%Pk#NmAder?0ho8X|q4H%YF>#PixXTxi1O9*+o2QQr&%+pZ~% zYfngX6Yk@?8ar?dG9SbJ0^Jv^tI^-FILr5?>J2_p+a6zwsP>m!tGxp4hUZTiNTr7) z6BE1q8|aJG9WN3RwcXq|zONe-O%Fj9mCLmIXD9W-b=QGp!TW}zvq;~|VCjJ)%F^rl zr{x_HiIemhL$8)K|El}WdeDUwNq&m~N_V z|KjD_!#!#Uj*yrE4k~};JG+>vm$_Kxxoejx1{5=|_Qk&n=Wje8ic+WYIi5-U^QHzh zdw^s&b)E@h1cUcUJ9^~GH|qp#d#^>wZ;a2V{Akm|X}nuskIbN~GBVBf7_PPL*!-BXRh8bda+1y)fZOmLs zV(oZdXJ%=;Np!6)M=0$RT1srH@fW?2Cbjm>ym2|?VemlVFmXuK<7jYG+{2i&HxW%< z1D)f0iyrWb?O$0-YRG`PVYSil5%z3hv7G6lYO~g`4N3sATWcIP{78M+0lq{7M|J$E z+aLBZH^$H~M(0IYvgeT?Cu`IAoDx^)-K3(Q-4_*Sox=L-P~9^TdupTWm1y6?KD0)L z?8@%1*qlqqs_G9VY_(U;$>z%@IcloZEo73yFYk;Mj*G5on6u?CjNJKq)3q%M~2W1v7H5C!ySLYQgPjrt=B{2H`lld#3TRd_#$`(%sBEM?RWG zWQY;BSEE%krFN_8r^LToytgGKDV~#XQaU<|cr%P>_`63v&r8=NrdZhsf|JfRi7C*> zN*#vW){$+pBA{ z7R-{1o8#4lqcvzj>EYW|1+&+x(q-w2NsrD7GlbJg@hfrWs-pf6%yZ7pO?IU~g(pnz z6m&l1A1Z1CzWJzUkCz6;jl|_6+cX|gxpZ+(3*pJ0B1k=D5;Ke$K>z7se22Et(CxPz z5)hMf%JJ)zYEFJtqd$*t-*bTnug3pI6Ed&&PNjCmAq|b~#fG_XS*DzjpQfhzBTc88 zkfw4ox*KWvs$01}G988=D4EJ(U*xl-rt>e8lA!Y4aJiF1muQ-E8;G!pLbe)-8fcf7 zE#$UrQ}P>>WlD>U;q5%UG}zs6qE_kNU32}Nu)O-yKg|$fONHw1<4B#46e>?O4f0=g zL{M{Sn;EXP?(afduqr|NH4I8+fWr1Og zs{B3EV~{kSpGoiQOvBeOGa8(IXEkKgc+CRbNl8Udxn-L6Z}*%*oQWLq3Kd}-(w2QG z^o7X%ja#QemA*)iuGZk-#1-_>Tzb+S3_r1aBatlPV^lQ`>uVm%z_zA=5{0BMCO4j_6k?czO`-L*%|cq6j{4{o-PiFL`HydI{gVGmjWVq*^=z40 zz&sj@hUecUHS+B_^+brQUCB#UM~M_S+_1Bm|ZUKQ6>r7F{zl3hOLXfA@&Y26NA43tAVZ%EI^Ph|U|I#5wd* zXLJL278YPpo0PC4rK1#}rTkOUs5C+8B}MP76MC`Ud(%FLJ7gz&%d+z^jkt6#-wYTX z83XO|d-71b!@sjl&BF6eRl-({d5*TyZ&j6x2~Xfjn}^Q=jlFv%rA!c;#WPHRrODH? zW{pWR>Nxlk=5y4hsKZsuh1i9214%kY+&F2}_=?VCTL;`HZuj`!-($(;N)DZr1+9T( z5)li*)p|U1do5Qfz|hY$jpf}q)PwsAw=_4poSk2`neJLUk1d$ypJz1Y? z5n0FJjnl0I@6Cw(XCb&cAAp!i{raWm=xY7}&RGyBPaU)i;l|Z5*=n#g{jKaZ*iCyP zGiX1wN7MmnNiA?DVcfUoY1#QL+Ba=$V3+hZe9MKX%GV4Rz)`qfDLY#773Zo`$Dm!Q zFOqoW(fWju$4(kve`!ytp9$x;i*i%Z=?ZKX?~!|t#wLBsOoo;vIRwvHd}<3?Dcskb zyO_sTGg=L$ee$xsqwG*hl1yo7x%ZW)Pw`+WKO-n>WciUi%Monm8P$yUbGVbOIbb1V zV41U2q6Ef^r*nCKZ%2334KtWrt{ie4Z?q7{TW6xDHq6PKdVCazcGSq`-FUnKKc1c+ zGIGPVriM}fmA!j4H6q9h<8_{`Mjj(4Q_wHKa1y;WrS0BhAJ4CVpCpWU*^-9i<(n3p z-AP<-LUUWMrQe|OQ+P((tUuffqe9QJD}(O|Yb3KTP1bR_1j)R z5<^C+alW?~4(9AG3{u!?l45!(Y_K|h#_0#Zg@er<1zMJiT4-jkQT&;7R#rbVbSxmW z1vm}f9lI8(y>Hqggb}}mjAPQM{JYm4(sK4*n^#FV1M6P|p8#nI|JMn)8Uz|(2qOvF zU{~4DfM6^sM8tp;(N|a|QgLwroeW04eqAWaAV%y|t1dAjloZWEp2|G zd^z4x8>!9T2?9w>$f(!I>yw3mjRfo<G~GxuuWNJI*2XRD zkA$;#bSWkQ>u#oi5dR-zd%nHw+K5q8Qh)axgo!QaWe?z-Es!|KgYAWGXa*5R<{5Z~ zoxB-IFSN(yp|!wiavYMcI1UNIZo&=pW~&`c#H`ONRe;czqeEausXV%B~ioAu-Ba%%j;tcAv>a*$O9JK zxQnv%qR3F4UqRTgwVg`I6j}PB&VVI1^ZJPgWb4E8T+C3I=3u;P@xq&Qa5PRtV%GZI_>y#YjoWR!3J$1OYF{+KLLuEBHr>rp4ch z1(P{yy65qXu^)2ua+wXy%`l_gNpp9Cp(Rz((Ncmj{7um;Z82`Zk}z_mX~6QxCbzVG z0!p2pMJer01UW*BjO00W<*$}y>HD&3=x>S?i6FT=u(ojwrZgrXA$VG$px2$Hxc-)M zF^s;g?3?Zkk+-b4WJ%E00%+)m(%K8}|Em&~?0MKhvM|vDZ&bQSR9`F8=WCQe0`bhv zus*n_j0g-Mte&H0^w)WMbd`RvFV8pZ)fi>?l0S}>L7+;xa2xv?#D9=seq^&U@JkX! zf)NzqwGh|mh8c$70NQqg(fRM4PSN$2SMq1CHvV2MV%=qh7L@`mn<2ZA$~G03tn9Ss z*75*YQ}_pDo2$ zmn39jdnI7hLbCeHC1`+k7C*yIN*DkaEP51|E06DmH%hpX z%8NlR9CTze{%tB+mVQA*oxZXaNZ6UDg{Lot&VWGw_M7eA&&N|vP6#{s8&mMTRdakS zu%k%`&fCw1V>7K>_Kjt^)U!;o7Kq|m^L2!gmc7B>r@Aim`&3Z+qLuH-b)dF3f$r$%G;QQ%~eE>IC-3=?;2{rvsexUJ3o-N$@Ymy8zN!iydiPW8jt9%D$@U`fs-XU#}Y_kV&`|87xFqw)5!bZ^I&C9lhW1Ba$zkuq>LRZ*AJ!Y8l#er|#GHk*p;dOQ zGwRzyepr-C9n1!}iwC%qsG%*%(X*^EdY9agFAJ5f8M0*L`3W9Q{W)a;+z@~j@*Z?U z@Twuam@8NqgApc&%bb(bw4~Yj8 zLi^nr5L{W}aAE*SLmtk}97v`qH3-!W*^x3H0tfURYA-MMKA|4f%n>;K~ODdv-mUXp(rDtph@pHlrwnZa{eMnp&5IBd~Af; zHyS0Z-qbiGzSRgV)4~<>YJoGK#Q)E4oq<3$oJt;;HuG@=g~i*(fQiNK9k?GJ7HJ!{ z|F2dp!Ab4)sLF9zf6};MD9kdSFz3_*k^~)*`8-tfiE$lV3fpEQdS2fa3^>bnX_bdL z{mBA+Mf>9yj%>=_%Q~2z|M`pJjBw)bH6GkQaDNOwCZ6ub0^;G{64Vrd;Fhg5gnE*w zDwVn-F0)WQk$>m%7zK*TNOG7@@=4)gCc*C*EJM9{I{FsfGT>uL)bRh?;pE7An8^Qc zgDvWYCTO)I@UhHe{^x-h*#Qy(kZzHII_;1BR%h_}O2e#&Jj|PS|5eLC@1j>gC(AlG zfpwtaIwHd-li+D!$n@!dKX?4E3n_Y<{m?V96<7e6^~6D*1|Vd$1(O&I3jm700kG!e z!Ik8oq>%I(?85M0?Fr;uvJtYZtKICVasYF6w0?r??hP*({PQ{nDI_gYJJEK^o^=>%a*K#w4vn_g}zh&t921vRUe-egsxm z%WNB@dMJVmV8Hy*^M!)cHFoGj}{_l45)}aym+b(s%8+9(l zxs}ChKfWC|>+Z#LU6ZBX0EW3hw*oPK?VmlOSgGMGRBGRI9T+Y!^ZQL*-)GHoN`a3- zEP>EM*P?qL`>#-QBSUwp27xhzTN6eaC)3@BD1FU!W9rDRpiU1U)4&Ho&8n1`ADaP70!nQ0EOUCKkUowgH0uzx7BsQ+`IH0^-BZKozT&n#9b!)|B4;+gw*+H; z!kDmwFp>pfgVtMEDNe{k}-RQe+OCdJnh&)5|Vz=~fX?f(Fk&|u=Y<74Q4bvcO4?*aOVF#2Hc5#6)H zAj4eVZUo%m*ZQsA?$tI-wpOWR2B4Ez#XM@E$n8vt9*9vzPXY6^Q&0^uqR${nOHcsG zqzP$xI8pgvw%fYQn`ct)tmJ}K?X8Qien)gke-=*xj70(;yfZ)ZTG>Va4?^XZ5T81L z1yINHG188i`LGAcy*Gox$7aZV9}?L%BmSruNmPvl38L&9GzfPr(cv61bs#~4FcI30 zlJ}=?|LQIQW%Z6P9h9mwsWsyXRt&fJ`;} zoIYSjayicrxE;dIIid*0>z}zrD%=q&bZ=cZ5m2#f_xStr9OT)3LfE+>m9ZEHYFb(J7d|^Q+>*xkrG9)IQ;?A(^4+d-Egnk14V`H69AshKys&&~rko*m3po z`3}uXkD&VjdG%=Q6M4FXJiSaDqyj=;Sn1@aDoMttXplj&)nE<}CReS!1i$e{ygA$~ zlo9#W<;Q|cmvnab+`<)-3&{Ar@#XF`-GtSOmwTW>$tSP{$;rU8TYpu0XLQA?&3^?@ zyKjVr0sI8CF47x(b>P|9Aj0o_owXKGmL7{`RZD;u*rh7-|1ti9dor#A{%g%1aJBW$ zJU;7A8j>L-T~o+;Q5m9>ogPS&0Dp5Lr3n{Q~5{!!IC{;PQy;Y>mkOp+zTUai1KhIoG4^$SvDWJu+ zRPW%cPXMd`8hw48MSK89iCSRQikS;KWGrN*>{ncn%UGticle6h?oe3={_+Gt7WP7= zY4FkLC3ow4m!!iyflq0*_?`P|h`bwdx@4a`8wd#MS;>tj>4$wU!xM5Orqn_J5b5(2 z+b3MO3e}H7Ujlrd5hV_@paNLjl7Zv~1gH`tu~en={JTqQNiAJpt-8`9(}aLyouEGF zT5NXhDAA%n%ix5gtz>>?PIWzlif&fBa(s&&rh@G4E_+20~sIPfTilSdomKX?03kL!7WU=`oC zvL6@QKn)HEVrZX3>C@si=B0(YP%cnz5q4x)^iZm?zCORh_GVYkVvB&Bqk+EmHQ)lYUWv(H6qF7tEzzJysuE4v!7Z)`ehR3T z1eF)iA2Vc5+3R{euVIM0k|rY(f?E{;a}HP#*oW-1_Ddgo)68q3m3>017KQU|jqOzg zUW__j5Aey^5@MapiSB2T_Bu2%EpPSZddv^X)Ww;-b0mQ4y_g7aIH{vV~hcRS+ItH{1cwM$hLf z2sq(P|42(AbN`?jHQcr!jAV@U_(#|9PaLupZtkmX6KzkZ<*8FC28{};>hHvAtvNRD zgR3|#=0*a!ps$LT@yY5pFZ?dk(s|s02FFk3th=swf4Zn4(Wlxpx^ZZv$Ztq^!b3qC zMSZqfQ63Myk4ihnx)|Y~mWwit&B<5!k7>+*TvfQuLMOy07~y)ape;5CoruQ=_$N$A z0FwOEN_SP>_&@V3<+8zA^}lNbWN|WA*aGiS@9%S4Y@2mPgNgfJ!M#=PQ*?zg+^&?o z1Y2mEeLxFLU-HcXMSXnp?q>Z=$A-Ut=Gv*I29 zCL7u<XT)cgD4Mq>CWI=_Q0nbfV=TsxMXOWWg3s(x%0AeQRihLe%L2A5nBaa5yGF% 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 M5OtZN|2N@(0rx3}IsgCw diff --git a/wrench/reftests/text/perspective-clip.png b/wrench/reftests/text/perspective-clip.png index 7273e7396d8d0ef5d1ef487b059105ecea9084e6..3a836ecb2a818ec1f7c9f43f4f9891817b3b071c 100644 GIT binary patch literal 1753 zcmeAS@N?(olHy`uVBq!ia0y~yU{nBNehxOE$fHWhWCjMd1)eUBAr*7p-qJn2E>!N= z!@o~vt_)5)bzlZhS5k;UG*45+krnZW9*G-pMd>I>m_)F~FH)G{%9C_qRodVC50163 z<&OUrx8}3u_rf`A_&1#Df4%SB>sQMQxgRhvGW7{6JdhX))JmQU-#3S+=bzg*=dMP0 z@q=CE&uomJ^V^tIf1G|-q?GYj!M8teUf=9hak%r+pY6pq_q6=;ax<2$=DN_nSv}qS z)>WAu@ATPTJhI>HpZ0&Y>T1plPt&hAZ!N= z!@oXrrdy>h<2kd0vnwgYAeyHs;>e2lLyyD_xT18FBupY$;}#pn@eAyiZ?$?%teQ%iW>t zo*gKCf2K0+Tz*Byw@3QBbzd=kdHCk%&Fh<^JsWmhf6sFvw*Sn%d4Kb#taObrh)0Zo6{zk5v#SnW|Yf4PBbcsCU zujg-WM`|&81sCz=U8rSw@u>ag{j^RN4d0WdI~?Di+1bw!8+YMP?KF>uOCTL84nJ8s zqL`-mH>^+{WsZi!z$Ak8Y7Pa5Su&Uzn@kyRIW#2rHkb)0L#PLrG8y^G=Q z*L!bzZ!X{bKJCJrPupI9yxG0^NxI$lRlFBUr@vRIo8`E8|CylupMUD|yEHWTP^bL2 aXMQPNr1$sTzgS@1#o+1c=d#Wzp$Py$SCnS} diff --git a/wrench/reftests/transforms/perspective-border-radius.png b/wrench/reftests/transforms/perspective-border-radius.png index cb5d20481ed362bca72e576b8ac1faa71100c721..6868bef4308f9cbb907866b0ecc45639e0f14c00 100644 GIT binary patch literal 11839 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 literal 18227 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 diff --git a/wrench/reftests/transforms/perspective-shadow.png b/wrench/reftests/transforms/perspective-shadow.png index b065ab9a0ebe2e133041f992bce7311459e431a1..2a0d50806c0c8c3b3b6fb6d21d97ff7d32a26cf6 100644 GIT binary patch literal 10342 zcmeHNYgm(4wx(mNGi}l7nd5P|kH-qFPEjs7NF-3J#c~tGq;ulD0g> zRs~up1~Mek8Uln%L=Gc&q*NjTNli#1NI(kmnS=%~#1J51))%T%d)hfOf6kx7AD$%N zxA$KAUGG}^U2F4s$btQqFIvB7VPRqE_s+gh3yU>j78bur|Lt1%Wy8Jr-&t6^_J-fS zJ^0kp9|n~L$%7G!6TkcYDVOfwug&f}zO&E@6A-?IvDMej>Sg%hx$aGCetT6Nc8(^P zoao_EtFDK{>a_c+BNwOoZtK-Y?l_oe8@!*lu(+}KUifns79Sj6{kw|5DgvtrtRk?A zz$yZ(2&^Koiom~wfJf){o)70|&iX9PMBT?+*luzEm{5J|Lzk=fDdsP?t8RVhdiB1- zD$L@>^$YSZ?!_MOY;mcz_=vVK(sN{O_Di*H@FlTXzt}vRwalU^jq5r3Mg7dX=l~CC zKoo|xFmi}Jt6^F156=86RjI$9{cYoKEZRw|^!{C0SsB7XyXn!vUDy#jc0Oy-*86=} z_W1dfw6en;Ei7_IBu-}~N{@Tl&gU3gt|gB=Xql1y5vE>z?9BgzR-vp$l3I6rYq5e^ za)yxVfhg&z^yzPoq4IdTHy~>3WV#@-Uop4Ko6lO9%ATtHn7s4>t2~UHGKI9xrO#YM z=c;O(z`SP^mX^CA%D%LPhf}60P4>eN21*q%nw8(MY6F9wv2Ntw#$U8ZEuy!+)t8dT z^o&yX8SaYGl=_i#^t@ujNSzxJ&-8Rye0_&uee1^VjTSRPR(j@PAGS6bOTW{^aV`;3 zg|mi-O`_3rNO$k7R+lEE_(k|4u9IF&UB+aSXsl)@pqcV$xT-57Ybx2fGC<|0f~Rdq zr)Ao8cd+ltw8bq-_}vMfxK3tF#RFs`zd^04Ln3V^wdK@;h2nv&x|0pwe4>5i%*D<1 zEQ$72ieF}+%8#W+U)L~`Ua)ArMdrV(H5{Q2$O~vDgqAfwZP1^ds`KU}8wx0m)kvRq zNHB4){fB$@rgW3xRZ34oJ8B;bb!&a(qvoBXU_k-Zb&KjQkxfbIE7rP??pza#W#;$1 z%v+dprm%xT=>uCO!D&4y_wCK2Sm_bPB6UIY$(&Gyf`bfb!-J^@5KNN{eJ5csz_%v@ zsg_UdVoWw2P-rSU9lN?K72z+v{VL_~0H7 z_mh>ieV!Ci;Xq6^;-$|>%)2sCi3kBi--9?&8QJhSarv=;)sp5+4nt?8p6-7-VMKbw z!*&jf$e5oy|eXckuB&;#9BpHo7oU_Tvh?K z|H9V|`O4+PQu#Gg1X7T8Afg*($cUYwXJNRBlkj{QS=m&L)X&kXRne2vvdBW}>B%A7 z@NU%OvO)D*DTOZCL^1h@sE~s1PiyW=Gu{&dDgzH5PHEoQW%HV%XrPetJjIzDxqqOv zyqC)A8@(tjWbGFfUa8-m`jQz|f&A07+5nY!#t)~=>JBX-N628+zNQX-0CJ7h`!HM> z-qNv2?(3(INoKjHs>DrwX?6$9Agje`rmTYIML?Nq%U)qG(JpEem32W_cIS{x%c;Z5 zv=fyr&D9-);HZhaiP8&SHGr48%BvAy@f-uuVEIRA^<*oiQ`NZJO4M-b!#>qGRytX- zud#@Kl9p+GOyfS@EGGdX)^qbqM)`;6wu?24FRz{P!)2Fy$L55#P3~?V-))~R)-JSp z%43X1Vc`I}!^RYd!c)@0_-}@#@#4F$!&? zhyr&GSMFZnza@?;u3(tPmS?&)boABC*Do80)45ejzwEeX_pfE{UvcxBCM!kvS!jm* zG@ieX9K|QS6GYD$NL~X&FKr{6?kvw=+0b#jX1;KF)@eGI*9`RFacx2+WtZLC93}hZ znz4~5qZPrSFqF}aj&9zJX`2)*OY(hC?D9>E4!HF^Om3wTp6-pK24z=rSfx#8Ht4%i ztHaZA5Grf&h`7m}bGy{$P`ve_LfZUUTIv*gN#tXgi61`aGoMJC*~Mws?(WdmIa%^B zZako=`$c~w`Ily*23_H~bGbGLC52XDKE^{nMs$+VMdN6??IGfLT(b)%!a6kGI*@`5 z2J)XxkA~x9lQ43_WUVvlog$W6Tzu3mI}XCPift@mXU=01ZcZ<0roHki#v8X;@|3<( zMmL`HXX#cPJ&-TdtR%os>*d)%>i{#r)&#P%WrflT5BbHwUNoGIns|3fmbfe%zq-w` z(iQQQCX?R8R8NLm2S~Q+CLT_$*L(?iJA4`9zPfFoH*@*`3D+K;Hudm64 zFuA0sE$bZ?9z-oXFk3RjUmiN!u5M{px9uU&g_hvkgb)k|E04Dh`UP|PzEFkpNg+i! z1Drh#+$3FHe%933rlyTi#-XrLo3MCmd?DZwUPF3K+P%?X9~zWnQ@TqneySXT0>)zL zzEaLX49wt5i10Sm0W<#d`uE$TjJL;&x2bQ%;e)K-MP~>p5?XSF6jjfiLAzmdaGiQg z{Z8?!Wu>spMM_o>qOz2ngXflI^sDsjb8w=VE40qarh zFH(AWVq3D)PyXoH=H1|z{tGbOxeFQ#|Q?Z}aq+Ti13@j)IO znL9&xI{C~x{VkN9rET`fDHmbXS^@x_5CYH_`by`@y$zLTX%N^qcVy1C?ZMzk_@G!k zm=8qf*4v^f#T8DZmx%mz3T7FAwg=P2bLTncR$?rx9w~z}7sjIQznd|3J}T9gfIdgj z**N}Ud*`!@O3CBAJ(vh@ty1K*^wRJ-5p7HhIl#Sw8*n8KqO^NsM)nilX#NbVTk7SqB1p>ipnh2^O*Tvsy%%S8oZ9ZK zH;8a~mEzAB&X!ev*}T3+o(-X_(>=5AS+}@AB)DFIbi#AAi`3%1`#jsk*L5M+u+37WgB9ZB~*%wlgQ8j+)sO0LlTpp~9rW^b}UfHdh z>(nj%&@-}Nt9z3wx`;mY1d4$pX|ns zXP(ogc10wcBT4{}_rf?xsxS#;&FeQCKarzK+3aIG$t8v}j6=QhMcm;c;UC6Te=W_e z5;v{TUYZQMDdy(?jFdo&2p}Cj2j7-g)o>nck|klT#8G_-A__3dqryL%v`~zmbo-wM zRkSr;5`*TCeL=zS@n&Q58}e=`XETcD|AIFpM1UShaX#q<{*$EFy!(k2z5{a{Fz7K~Uj=`adaHqF)>{9EX-6mT zFzE!FrP`sDWJxf7nV&I{^o}kZbjd$X%)V%17N@-zuDD1EFUr9yKM3!n{Ljn>0w&b* z$M+CO#{bmW2Z!&ErvwPfe`&}sr(aZo1O@+U_J)H959ho!q;FdRfpoa&pItPEKnkh( z^+Q9-IYEGP=s`W(Fl9c(hY=tBE;zZKD1!@o6f;g> zj3vReNwX?4y~L&^hSVr7VPky>isGY^_p!atN{=Jf_;_oATP-Z&8qITNq9Pdw`x^4 z9)Ti@af0wm<2_&)nFRF2dVl~j7ew7)WI_OFL4X?0a0bi{(yFNw4=t8oQp=lBwTuEE zMDNCT#fh~}-loq{>7QZP9@YNGcX1#sqR~oC@x?Z#O<)-mQqPK3Xzy6znQExCzyb>R zvL!!rE_y@9t(tk2ynSH@=!g^wIzt2ZGTwuSrLPp^f0rqKDsdwN3Q=S&0rABvn-W5# zxjeCUKg|F|CCoC!&-@`N1jF^;%R`!>2=T>>P?@jg+`)$i=l#5>+6&q{u%^T;w566+ z!j8G~9dk41htEYV=SIl8E=S8sjX%<}V`*uJ z7g~vU(9|9d>p(-H{&ZA;ekMR|4*J;-_l#ge>%%wE`ta&eNkv>>k*5cULXnZqPDe|` z#AW$tmThR+a~NE<*<8@o-Jua;a?hOVNqyG{^^Eb=+)AO2;Y%O|0`ubz2T@HWY*WeE zsPT89$TVuwfx_f$RWZEqP7P_N6iONL5B8c|R8Xyq|FIq_AxHDbTjCaqyQRU#iC`RB zZtIut>m3C6E2?6sNt>LRHUX%Ae_nDozXFQ!V7$jAtjB-*iv&yG<}ZJHw$Y9@ zzn?b0>k^a)MQib*+;U+&y<42D>M4oWpGq`GNrODQi7$8m8d?DqQlQQYt?=lc%Xjll zcf0tfx0~jJP4h`!7>)|cTs)#QJO8yHe$U*UhV(`cbMhQgcMe0X87hGSK=Bb2h#uVA zrD_Mmm_yn;A>k(5G|2W|Uk?2O#*4S2DzQ&(B%CK^zSml-`hf$%|^!p-Dxf?^p>YW`%m;p%if>8;5 zPP9G}LcPhNWJEknE1(ALB{sXCQ;7{_%EcI=I#KA!g!Z7TQP#Js68#We4vofjp$MHj zP1kvK9O3)nj@bRAEjZZ(9qnx7ZoIWWG%2C`t#dKP9uaL7*b9*K6k8{4>*JGl-pu@x z%XqpjT!skaCq3jage#b}8hH`j*-FoIAU<|!01S9v6`qGc3o;h%fNrH6sS&9SteUQq zxN@X`dTl)$I-PQ8rrC;OgvKD~2ZKFmxL&_u-qR11%ZreN=KXM@;IhpGbj6Nfh2m9; z6`7S)70U@MhwvsnU*=5qD4B&eW<%d-xdxh;<~Uh_Wo3#2t38r3upl_M(p4l;wmM3h z&SVA1K0bY>R({g=yP?8yE%vHRgr$4RmEoZ)9VH^rLqt_kE{hy1^GW|M1@AI+nyFHy z#@`%Ddd<+AN@%T~%n4CMMAR~!$YFF{tD|m(T(M6_`^&t!C-8JnA9)PU!3|3<_tG2M zQWJ{j(yW-GYwJ1Y2mGF)2WC>PjMKoX0kZasl%4%))YBQz9J)dt8+)KR(fHLJ@N$3B zpZm4RM?^#z^|~l?z5X@|m##qmY5SpTj~S)8Tt9Z1rs*V$JO#HU*>S$T$&;;TqF-nB zddYF@GLbkfNaig1d*9!DTi~fK@C~I#ioi`)%mA(-$7%=qL4_3fN~s4#TjdMrt%E6x0<_3!?MK$wJM@*Y%fAxBdk|yT^HJ;(}BK@y4&o6Zw?wk-b1)5b;6GEQ#Z z9xaqWtC_78Pj?jg`IDiy2RhOtjlgM3gQfL6$I}V_o9s=!A*WkFa-AdJl`D zHQcE0Bia`)w)Iw&OdsIOT7(bE(CabtmDb|pTDTrFDw8toAbnP($B1b3v|`a}|1^>~_QuLBpdH_4cUJaUdWU7#`+~$9$I$ND^0wB~ zt(G|(!%@nQhDN@fQ25FV(`fv(KWNPx{*SH~BLz>tjIVr2_#~|0-tohoYPdMEu&{wn f!~c`NOEgE?_N?k}Q*ObIE&Sd-u&?&57lYDGgR$WGa!2l7IpY2tk2+epuaUUhaPO@9RH&fZy+& z^PKPVoacO>@AFyWt{Bf{-pkzF+&p7JI){c{k^`Zf5Jhi%aIB&8YTHf+F4Hr0dMY2z%DkRR2 z=zNAmGx)Kdhy=lRJ@bE@_&r#@Fac-V5G>gGEL+bSnlWnGh6xeFd&`hv%4o{gQ|$FL z$BKm)J88YqZGu{3!BiwYBEg@oU@H3j>6LXIJtOvo|1yyWjpvkC4?wh=_w-!KU#+*k z303FNBmCzgg6xU|GvZaDf~_Z}O4~!#>F9^+1t+h3+w~i_iQ9PIN}UDI*rg6Z(4^~u zxe;ZkV*T8e`}~>X^JVr(b$27I0q=!p2#Zn1am(~x2%N1&dfDNA^a*H)`7Hu?ifbq8 zto9FmgLOqCiUROIRk|Mhk9r0NnB|?!f6cA;2RzTyXiq}MlH#@JiZAa+^D_N#(-;2K z!H}q9wdZU#Qfj1J9%(_2Z-u})tHyav&2_-oy!FnfLC&YsN~7}O59#(^hB9Gn@-ico zDMtk;EhMD{JTU~aEK^d1;hK|hPrp3y?A-1U zL4*z-L19@_oAt&d8zym30Cq5n(`pRbbKOVW_b3zvwZ?CTi(#Z)>T|_U z&#U_d;i5`vKeG{*^#*~_##EO+4pAc{ifRCRCd0NuUkgx*)UoBK`o9FTMkN!&(;QZ& z)B24%7e&+GtWUBOo$IbJ*Q-&=FI8_BY4Kp*kcJk9s0nX%7@UqFMvpahiYqK2t~WoZ zYwj;E$pFzH>VDS!cTy}eHZ9{1?MM)?p~`mBrdnZf8T$R9oAtV!tUvh9y#oc^9mtmv z_$PjPy33L~x_2#9X$}}hig$j2C2i8->2XtdZO9m&!ZaxI>)V)HY0}Dz1uzm!XMM*W zwAUPL9KVyZCqbCnbEYH{S{zZ5_9!;fJI%YiLi^VfwcpURd>KHyYjUv=feA;nR zoED4R7n7(CQ4_Y`D(Y@i--tYbNU%lPA|ntz_|DK4`2s+GA}bS-;^~O(RK+M$p{=0H7POvp=80XwBwJjWJliw zs4i#NYP@!u>-=X=`WHTqWy+Pe_%NN)5E+Yvw&+4Ch29r1lGYbcNf)cTN49X}BQ+fI zgP5`hGvQ4=#g`rJLMo~mI)^yALP70_3L#1~smFbg0D68~xyIno8~kFhL`jbAR>3~! zUR!T~q_tyfS0=FaW9^-d?^@QIgF`6@ISD7J+25lqosB`yPs_VjD{WuqAy+iHODkG6 za69W{vW0I9W)IiqSU#?T67080JP%TMtm5!k06c%Y`!o%$g^ z$8h_s&S{sgblR_apiGxmA}OrXSWPNIbdeM2*#try!!6Qo?Fxi!nPkh$L440h`2{%1 zC;KHW2$s_R9eMV%GlK8hXNR3uT9vA06(PPn8zVR%N!&n}6dk{nq`ZcNlIrUTeSRiI zuxFzN?#U7VwT@vD?3dZ~>(J)2X9Oedvr|m6G2aKyvK{1UW6QIO-tx$&5Uj8yym zp!xeAUB2Y$Gvw(lg~CBuL3(y~SmT(flrE%(%Jq{IPzpcQAus2*#(D2)5)rcE+iRoX zeHnwYAg4G8JrB>lZm>HH$Q2A#*9K3HCR$cEn5?W}%F7C?mQowQ5qV`dTe5c$xbm=;o!hd-7xzny{!Vih8k$62rpp158P&;(f@j57 z56bFJ?@<`(aoQWBw|&Rgx%>e_L-7`2pe1()0Y;B&$QFYzXt{}=A3#T*5Rvbzn1!w_ zl|5;Nwq)LhHf^g)^Ttw7%Nm2R-pNgP5s{me0Mg<;Kj=1rT%-@k0+Us;Q8XcNguATH zUDkL~W@OHP7wGT!^OgG>587|4?(I8+%}Q>sJq%aWY@nC)nm^K^X+UtbeO62pn6~`QJNanz-tz2Q6&%fJXWtVAt)|p zZ>|P5#HMG5EN#uKXuT`$%JzY`WW0|7JMh8+r=nr4I~ijc$wV7( zyGEP}Dx1vrxzz;%juTtXc_U@o_hlexh+D@zdruCh&*Ym8fXcYeZ9fu{)MSGda^X>uL4TRdILlA!b)7Q zRDE6kbqu?|F)ByA}#$2VyKIn4gEs=9d zwK+Sv8a#b&oQCm#FAhQ?tytLAy=icDFXhEi($}0GEr6c5{3>Zu17ClTdQJBtYv_Mu z{Xd*wFnNGe07GU1Uvz++8V>fy0sGVQ#fR!pQ?CZg%XRmd5!^9-gi8D0ZK~{OnW=(< zk^`s|_@--Nq>)$8Td-$?CIny=_7y7-a%3nscepbjp0xu*12~AP-6f{rSI@#wSOses zL^^bTgmG9UzrO$75-K!@SIQL-o^sa(1cm3z=vkLt4DAIn6a*vUWiY0DM=$tjI|jN$ zpxysbwG1}|m<+5QB2%PjK?yZ$2o zHJCv{TZ5%)rK|V^&+KlnX7o6~L)y+T6X~n)NO?b^h`sRc+?#xsz zbBQpnyZvSI1Xol|HehnD`{n6)7obYeou}Sep7rxP?|D82cOJ-Tt{i{6t1cHJ4*&38 z-~>Ro^{*%KhHU8iF#URp z&0TM};Lb{gSGaOFL_?taBgH%Zr!-`NBEeOhD5z9Aja7s)?IW4~j@NRpuj!vXHFQ{7 zQ+F5}-a@I}jkS#Y5~bS$YOlI{Ks%{}(h5LhAW9bk<^$vfpPTqAluX*S-)JE_EmdSy zDAO_G;vM&C{j*yN%Vy7zXY&)=e~HaOq*(?rF)S6(SEr0)3P;)5322Bj1(B?AfDJo4 zIe`1Pc->(@6I#Yh;lksu2G|9_egS6!?=*07lL_3CK|ow8TL(v%w{{21_>3^XMP5V}ox;OO8^)^2!hzL}j+rkxBrzOjG4ItUa8(b#f`@P~poGIy%o zlQek5&xrUR2ry5Ghy$A84hUExye$A}ypd4))HTmj884FZ71-Y;8Q^_vK%@&q=Y^gu zvATfqDuu-Cp$+cd#=-Yx0Cthi$vuRz%m<)w{7`6BM}pRSvx2#*p`ji z#@1VZvEHFTT#6qhr#%`zO@_RoaxFj0k6qja-B%5tvA1*AA7Lp?#I9bpqp-!i>aQSHTHotxe7; z<^m4^VeKa%YsG-|y0~_tXX_0pqD(ziBvblI^4SA3=DbonD9kxKw{Z$UaCPg5z>VA3 zJz{?2tKi^MXkisQnL6>;AUw020POC540$tR|g?JhMf2TK5NX6{U9 z!!-CCChd!QaG^x^Y!I63qOn==fU$#`z-A8ul`+yaiSwEPy`mvn3M#3K2-a?_&0go8 z^h$A@1881?c(XRuI|-;vx$%VD?HGTFp=?r3o}A?6Z*)voIi~a9fO9B-XohobY3lBR z+;^%`&Bg~Koh4n6M*Q*Q9bFXA&ng=L)7;;)M8>~_we_-;^W$U(-=!6(oX>_pxv;8} z1**S9l0KX+hgCLdq(3UsfgSjRysS4d;f-2xjn)Xl1?X9p9;P(`ZJbWwuO{1+P7^@3 z(R()#6Iz54JJ-a|eH+8OVH*9BAR__s6KyJ>;Wz7zXPLI|2gv-@%6VfRYTmN6 zDxI?g3!=M4%wGi^r}HfN5!<5|V#Bml7p26A!DwJAPLh@tFZ1LGsbxkgdWO1^{Mmt- zHDv3Ws-^5DaFD+m5%MNwn}&NS*;X&4=0NJ^XHb1ns5M_S1Z4Su`gpj0ZBmYR5@Bhp z9xs@iAv;yBSyG%jp5M^ua(2gIxQ1BS0Q9||OF%#|%z6vM%i4|sL7RKz;Q-n;dBzD2 zvpHN@JZm62@=kiTfL!6(tbtcHYGSqjD7tBY~N7X=w=Ng6silX)koYxTV>)n$yXe$N`RzNN1rp$EnQ*B1~g^ z#64mImG~ao==ZV2CQ*}d`Bx$8;^-uW`go*;q!wFi9F7+X$bv%J4>J{=E5>Zg><;@} zE4DUiEJuYpWj!828|6cD<%7BSM+SGLP4%v56b4}gLAoMGMqhyW2w{GC-YEcUq;9r* zGgAj7kU~ly>r(O{nu&RGpR(fAml;g&q@$>WW@BBv`i^zeK98HX z`8cXqR89hgDL>g+CI?nPI=f39bM+6#l6bEJ;gS^J&;rAA_B;>*>^nDB@jcSQ!YOPg;w{76{xk=no)k_L%zXq9Y4@$ z7=BcGf$-)n=s^)?4ECdOcrfnZ#}bNeU^8BhSx|`3?=w7)L=@ zW)#TpAb1cuYaMOged0Hem#S&~?~WKKpeNRhk3dZLLL0F^_~<(y1BEF`gPK>K;gQ!SjxVPzL*Uom#3+iH-;y^P`d70=1H{R9Aisk%X z>C4WYXu?eRpbU+qFo!zlX2vZB(AxPjN9k`+8%=S2I>Tf;BxY@zFjwE7ol~QXihQ4U zMWixekHgQ^(F2{w8?A$#N*{nrQTWg#em;_`;NhOGEfhdzfOh3m(5_@W?6!nZCWbqv zFF<-AQ9+Sc`jX4f&;*_X9}X!$xdL^q9N5B#g=?2@>=J?>{ms3fj|Z$J`0W8vK?z3?m6SmNl~8o(IJAhAc{8@S9jt2Jz>VOMgPW8FW0@ET10jZq*EgOX0KoxTkx&GJLs*tMyK@1}(I++8~>g3X0Hs8o~!(_rE9W{<7tXWZo8Fd)s-x>RF$mkR~4- zca^~hP0VML1<7pt)@52+(i7OZQ+eLKKupf;wB%lL`f4~Rs!qL64NQ}LP(nyygy-B;te@OJWuRCVE(g3#(RKlpDvuj7o`glp(|7B#;b zxo3eeWfjP9jxWl_7BmXjIn0|5=WaTUEc1oV7P2yw_x__%?NzkqyzRxkUyyIstc+C(;H9L z!-hxI;c0FhY4PA;3aIJiQCZi&AN`HfYXw`587mU6uzv{lhdV@E&gCDnrk9~94Schb zMvZ*AuVpC8?@?BtrV*ukv1eZzBuX&&ojt)eG~z%TzDnbh{z3 zdhz?N2)}hn>uzs*F1DXJ_*lB4I%T|RnACrpLqsvI&?xG6F5%_ezBwnT^EsSMsw;-s zn;KTUpxiw05*Q``wSBZmQ%<)Gqexhf!rBnSl+M>F7 z|6cLCc4psWM+;vWfxMIoXO%0BTMALjsvMWY>tt3pVc_u(Wkz-o032WcX^Vot} zCeNb~%RTt$;@9V(<0?HkbvGVtbNWgldamUBtmq>;9PHwP4+q?|9cF;yUgHgmCDy|D ztx%bhj7o}CE>#4#COqDJD5`a4(&HXEaq&&RT$Y?}7FV0OmrZZc_S8uEu)|FySWPoY z-k8TFA-etklqiG{zo9b=A5gtfN{QN2JIaOoW1Rx%Dt2o}ra_?kfG;5AbU7vDKS5{J z&u4E|#ZZ+l5Mj##aR^pZm_cyr4X@*5b{AX8Z+<=c@?%EpH9tGYba>vpOP!mj)M797 zy-4V(9VLh8V$uqbQQ?6sT143jPn${Cro5-D4Aj(h)32)_4%;lW2Qn5 z6R+7wHoptJ7m`*R!-uEgEh>!qh9(&{`RX~Beu{o%?-Z{hNZ(}pLlFe&6Rr?f+2Trb zE!WwPygeXDammC;drBtMHHq84e@12AGm8)GR$h})M}@N>@MwWHd5-m>$TxE2T6<51 zO#(d&>p@XF0%v{6eyZ|n>(uepbTQhX_aRbUesCjYx>EIzrwdz}qC`i!x7^vt`T|3- zJQRJYD2ie1`Md2MH7`!uy@?kWt6>DIVJoS2{<-G3r@OtS!3cd(I6}t90)!3>w?Jgc zjzdq1gc7UKDKpnm%Ji{e5wFs1jEY>7CJGKBb<{_sysCOSjRS`xyA(iKG-IR~CvUBZ zz0zvgIT7iH;=QF%)2PrK6Z`HptdI|`Z#MhmPB9_n2lLPj5(RU*hN3HG@DXG}s@L@c z%&GdgVkmO@&bkfQ?qaar@8eEehwb{%Au=tcjE!m2=E=dtn)Z^-G0fsTUwk=2GeU6h z9urH2$JFsKnO_?PyQSbjHNd~ZEpZ#^o>?>>&>tGEbG()Xm7-o2hI0B(6piS6m-6V@ z>L+Ou{2s#{NYu?KEyZ~p#3N~VVOZ+o1-8awLONIq8y3by^Yftv>KjNlG}4n}1tG^Z zYGzz>P>W?J32AGdPS4uhJ1{{X;k= z84wdod=XkW9s$(5JL=nCVx@={>_nO>qCpa2h#23$>uJwOO&n-&VT=qh@2Ux8^ z9Nn%U$_cbVH*lD4DNz?LypMg)@ect*@Dl_q&V}tryuov_hz(ot{X?uvaHO7vE5B*T z$GPVD&^}O7;yS|ot**Y^{CN-=%vk2~dI&5+V@K&(HrPQ*G1_ayZ-^H3wZNC%0Ef-W z5LBgUTYY7jD#+U@<;~I0jxMzUEhpi_;TTcOI{NmwF7&zrTwn`*Rwv7JujmNA5Mew& z{EllNQ8TAp*91Ek5FTR86r9RFMDxmr#R|`(5HQ1nn%(shGd+Cos)$S&ztQT~ zl1M%5R`Bu}wf9!y8tJpSQ*QdEWmAytH+U+&RLYLie)j4=u-IaU;aS9~S&cH=Nzj^- zw2Q*SbRS#;EJ<9jjH;!9JOn|^*%Fox2m_%yyuA?g7qb4xCLKM0@`5x2cRnHx5G9YkU{wzOb(I( zGe2K{@;_K|ug+1JlTbNcE;Qs8+0Zy-CpYNn2AG;iS6)`x|rLS*w z#kW>~K85cu(rVdBO;G&UPdFH--vD!D69*~82da%H-;5^@wNHoo`+K{ZL=Qu;jU?Ud zGJOH}8Y21^Xub!U`ZLIhM%~YiNo!-rp9QV9b+0mVT)Iu45g#8laE5+HT8~(D_YV^c z?ezkP$JlFYiEHkc0jt6_?}|Hu7}ObWX9Ys`$m<;lW0#!|Eco<8%6^ z%rO5A)tT*xs5Y@d`um2gpW>--eAiYv@4}5Fkj;J_$E=8yj@Q)12qV`7VilD!X`gIY z_PTyawCPNg1rhH{fBsN&Jh0vz4*dkI~iRyCwMDI60Kbs>+;VM)P1Hk8yp$+PO2G z$x9)Jbi#9&eMY;rkftBWFNfeOO1m%|c$5+~K6yu1mfns1NmxEd9UZn2CKlw67ZFmV zF62w$>1NS{S&n@th~YbumJ(D|*9&(0JuGqM+zGc| zna2b&Rs;VHiMIhs#Ru1xfMxOZ)Vvy52oU(XgvyUDvjs zpfn6K_HpE}xLzwk5DE$fl3suyn0ZBsh#jsf0bXyVt3a{~Zcf!FL+|h zqF?`@>PMPao~`9SnZkAwGX|UO=ZCxLX>8gy+2X;T$`t=J7A)IZre(dH;~Ggkq6C`o zbtIiKnt9^7tt5RL@oEY#?H6b$8I24<;q5n>f{8V>FFnhQ=r6te$THi$;{4jF@sOf_ z%Sk~;9{oJqw#nx`gn^zWEz-07^KBp3)2=l`CFo&4eo2(X-`PI8!GBU-KflUYr67TL zY_rU)53{6$;Q`bKLjNP!-G`A6x!KU}+AqFbh>5jy7#7P8JjhSgYV zB)v;X^v{-Rio+7R{8reAawr@P-x~B;$N9OfziYl;Qz~lZKPMbHXx-;NW*aB#vQ&I2 z(PJl&w8AM#=xkv&=E}$iVl|Z^79&tXhBc}20E;!aC-D=~-8Il58ht4)^S%iUH`$~T`t?IFSzoAK-|-GH zqxE+le_RLLONg`t7fQldFe1dV5jM(H#PAV>amVf_e=FLZlf}+9Ck-oBW)ZpwKWw1B zl!1J6j42dYs@?;VqrcpB)>xkK&Nwlgt9;5%d0y=LdTU>)Bu4+hPrpnEdId3xKpmg?C z9@zY+$CCxsap=iIv(gyiz9Et~R0AN&K%dIsOIbK2%OFVAkA~&AZ>ovaWwj z5{;V)ut9W(QGU;VuF3ky`~X=RHs&$a-h=Kq0|)+Bk=aUO$fSs0Q>Rm+t_s(2oqLs+ zB3}fYprwze0h#S+^D6I(@CIKmEkn6wGe@dbL}lKPmdNQ*?{jT=qQ}=z;sYS;76RUr zNtMo2q$|gorsDjD3IZ6fmwdtsI1r)vYJ=)V03K#l&4d*NCLvgr#?-4QpW$`e*1P9SHC?Z?Z_@Z5NCssp;TP} z8^LRaQ&^Z)>&xmt&f|36a7_Q*?MS|Ent&AzEbSaw&_{&cb07lC2&r(oqiaAm&|ycE z|FM4|Tti}vXZuJZ$RlL-RU0@8SbDWf`N>R-Ui05`vqzfE@AyBwq%XhBVTDfu*nxeb z6Hf#VbJ0Kx?a%)UK^XTh^snMP>URna8-QL3?xbp znK*LD+$blpq5LMHDKU2Cdfrg2`4|y0w1zII??y>Tg;(mtZ0IwN+2qkHpBQ-G6jxZt zxjOwSFvGD~ym4iFGv9q;`Kg{bFTIoK;~j5I_1y}Mvj&COZu zOjsr>+W#`s$c>Gw@=?E=YWKWLW_Vl;waY@_P0G}+|PSabEY;5+w&Lb8*|LQAJjfuW+YKo;sIiSeUALmzUIk!g(%6*&}3B|bjLSR^8I6c>dvb3krBQj0Nq(&>a zrtR~BAg3h&uh4Y}s!b#q34W2Q$4Y4WYf0wN5HPG<{p!jl4i*S{t~thUSyG0BKros) zhl0_jG_HI)6Kumt`ipQxS}ae#OEove<$MX4C0)xe%x9E1Ck|c$E4YxYkz)eDGE>CACD^~%5D~F; zkxPk&)(NPNQScFt5rIguG}?P7_TQ^7TYyBkdG4{DxcxJ^8bk8T^zDsY7Q$P+0G`-V zCck7%;Q`bG%Y=r+R)P<+If#N^juAOERV)sa$uvI$!!LUBZd0VsqtFb%ugnCLOI4Qd zeXjjU8mV)%mV$Xq{V(aSAsD`aU#l6#tQ(7QrWPdLKy7kHk(a7s%Bh9W5}SOg9Th9T zpR39fJp#ZSw1X@kj+9WTniygYd&*6Th2*76=FK}o_~Ia3m;e=2G5&ijF%m$U7atL3 zv8E-a)BLw1QBIZ81K-@qKq8hNHX*#bOu(U5ehPm5+(N!s@(I|?2b6Mx0)E!nO-KPU}N+f%wm_G!SDh4 z4e~^6o&f^Xn_>&e|Hyd475jX!7txRDBlB0?^@~T0_{kA2^-7MrB?4>o#DQeGtFa z!{3C7f!>+UJd>>TIfrxNrB&tXfUH5xJb1iVFqTDMo(Sv8R)?V86b5UdfB?}<&POLU zP%^=^S`3DLLs(&eJ|Zkl3{}+wf84?$I0?V*q^Bepq+;)Wy$7#^`?b4@(L(w9R$R0_Z`P)(RnN9x85FFy`c#B#D) zIj7JW4s1SIXH%$@7xEYbWzyhA%+fQYAi2g!0FAFB+tIqa$5DMc_wo5V#SswD#BuDf za5k(&`}5vc(P6%x>VqJ;*)tYz4E#@J?NtWJ{JFFGP@6}@($Mv2E4>$^c2^MXQPw^m zy1vmRZP+*Z3(SmQmhmeMEN&SgVg*qb(T`+U9rNw{>g#|s*%jz9^az_f{>XoWo27<> z)D{{=a$N^zZ4-+Mgs7)j{=Wx4D+18*^W?;i*5T?ywEU%BBQaWccJEuh2qs#=+91l5 zz5p6zJKFu#+8)sYa>#Hx(g48_WD^n}P8JUsqvn_@wdfL}HOZpF#TAh#?ZRFue80Gs znT+j<<;3)CAMqb0AEwX@WliSm-5{W8yZy0^dI`tIho{@sQJv);EURASxfVMEJovTa zw$|U1opIRCd)jy-gMh_ATu9}_d47|Gi~&9R|AZAlBck7%2l+bsY9vZXbpOs>9^Piu zYRwpwPOH7!RyQC7%|C7n)V>H%;|RalN-=eTG4|!N^M7px|9zp zMr3KpF`1Dy4OepnUv%Wf<%Kk66uJ6`Apvqy`UUzW;j?}CwQ8pm^rzYR-?uuyjJi$! z=rp=H8aATK<7uyg{F8dQ=&N|fFZ@5G@&7hRAoZ34M$YsS*0$L5SpWZRMu2nm7Umq4 z;H>=9^ZXu3htjxe=|ig>w2~$OXP|P<1kk{KxXuVSj!~6F7!-|0ZI7@# zB_eS=Zf~bq=l*^T8!S?k-Q21)UWIA3#aQP)tgKo}6Fx%qDm{gHuwf06xOe<`8ky;X z)|I?@;y;>7o&QgdO&8wkLR)%=D2{6~RBaj@zN=s%6q9}L7xa;b`ka+2IS3S1CNSYV zA!|6k27+-1FhfPI6>43fQW<_$VzdHaqr*d_O8t5mS0y!0y{0zj|Eh%zO55UjR!g}o zRKQ^F^LCBszCtWbcO$5xR`_E6YpYKSK1E;#`H%@Qs}DV|pby!PhwQtdR1r7x&Kj zvg*F5|NJB;{qHKV>XA5T655$tnm&&@j){vNTBxMruF#3C`4w5N)<8`y00ek=S|f}g zxGu&9O_s(a*sYd*prd0oKCK>|J}NY#9OqJy+h0r*CiN}GB(Uc9>pK~JEGYlb4dgxp zzh_zR9+JxNqcUxCBbPOM@F(s2B$SdvzSlnXnuB5Y+Ndr4qwLOs`1vA$^@JcqK?Yzq zgedkwU=uNhook-$byXWJ;gYvE0-Vvk_u5r%t3^^~^(FhmH9?n20Yms!f_G{u4*^3f zF)GPY>ncN#5?Q=W8hN};h*Z+eVuKJ=4NGW-T0sY2c3k;sCVuksG000i&oYiHyHWn% zq}R+V?6Amu_7@UixAs-4MURi|>W)~OM};Q_5VuW=NeWsPtSvZE6*#}&=)>+f*^C=b zY@{+^cF3=5s-r>D=CQhyCo`KTb=(BqI{5{etza-*4@g9T{#K9wtTlDEPHrCm9NV7a z;9l5yYWB?!{>rcu>NKF9Hn?l91sqU~8Ci}Ixv()~$wtL(z+9>TtMv`OyVO2Gh@wp$G!NDhAsH~X^G^_gz2fbBZ?W^;x zX}Ns}-X?Lw+n+gfN5qdRhZM`v!=9K12A1oy0kreK+!eq0`>$g583bN>2rppdoXb^t zqS2I~h7T;z?Kc#W*hnS;x~48-L~>NTS5i=px)e!MHud6g(C_?nzE0!HGq$E6Ml4&b zP)Q*B_6VGN$0r(tabtvEpO03V!(Q$9d|P(_lg`LbEWyJk*`aw(idkZ$L&uuMX%|l$ zzt;KwD5s^-+Jb#ms512T>A;w5GwgHny9C#TmWlv;6@}-IQcL(8o=$m@1cJP&;W+w% zr$r3*7f}&%=XB4Mf4YTo4ll!raTayqC42qlRt3=`{0QKj7Xb749-eI|Q_=ZtrkKQr z%210q6tG1wY#|Jd0OCux4=F4+|G7nX&kh#{@45qqz2E*J^x{A0_5lL{cud!}8W~yJmzIeK%79`o`$H5e8t$6?#~ zHVT{o>DAu_$YUeK2U!3~U|1x+=?~YtQ}GU3n}mudVWED7Or9dE%&{UrGj~1FRe27y zgB&DcMg|b_H4sG*$i_clcm}!x5ku&VfZY4od!0;q9VuY8>7@pkl5+4m{MA7}aTu zVl19`T#DZ8Km6WyUVgv!1?D;YA^Mkz;+NVmipblOZnm$R8+GM;OoU-s3;9cno-EX1 z)B5Dajy|D)a}f&$gVzF>H^>Gg)k}OhR`~4|`BDA_b4{LTEPX@Eh);c0sWjkWRNLi! z%$JBBBT}S&z}s|}OnSw-u&o{&O(@QN`e4$$G%USZV5)be;`zVov{mSsUALbaH-7}^ zlhP~4);VeV!=G;{?fSN^Fz;?xMAiUeQ2CX*-U|ro6#?P-TE$+!mR(OTYs)P~9i~*# zeqP-=YFL((q)iMnA!V2pntgRqxDld;ihZY8#CfQgPzERk9FWiA#V0fRoOLZt%FJuj zMod4sPC|>dLBj=-u-Ij#FjpTjl9Lk_Jq+_N5Z`z z*&}t|N`6bh(#W_L1>$}gb~8TOVE!WxhQj=RWNru$?tJ@if>oi0Xle;Yk^8J7jwxeX zC-mI=vH51<)Uet>W^>8+Gs##A3S-ZTYV^0*e`Ky`yENmQ*n%2ni*ITLM{g*1UeK)f*ktDHrgkBP z+|eTeSC?-8J#@4K-2g*bF?MH8fV=bY&MQ(mp)Y&Bq1!7$u%u-C5ph))%rW5~-n;6t z{ziLXE}Jc+hIAe-77wQMN|zW?SMz|1qls)F)!wX)o+n}htyU{!XTlp4_@Mk8pYSvu zXiCL3*HL?Br_h&Qv7E`8r+%YgHL?5-iEVm|27MMQ&%0J2;6OPA;@0Pp<5B?VbN8eQ zZ6$Fa4^LNK=Cwx0#$}>5TpSX+ba=eX43VyXTe(Nw3mzD}2zVFR6y6Wy3sm4eM1v(I zK>&017CV6zAsC@kO%rDeFND3p#wr$85&IPFo!^M<>2DM}VS6_dTp5D?Z9qr#yRc1| zyrszJAmW9U2LKmAa}2Sj_D4jfgbYoE&iSC)S$@0dT*iE8Pw0%1WwC*tdPoyo6C_zy zSs-A2d@=%gYJ*Jut!PG3SnZ1O2C#E^E6To?d;fR3I4u z>gPQ`Xk0^0m?&wc-YEX8X}fe2mtUm@D{M9=8~v_sS+Uk=cM$4~N_{%h&XY&)776B4 zNt~ZT5`3gIP>D+qU>VQ`SGc7>NG97#hZ(RO^3yZaT9?=N5;-L zv58a7_Xj-r1)jF5^q%>Ne}%yPyh+#F^m^BTKXXYhT$!i*gaCQ}JmDTqTLmol$Vb8sKP?bdS#Tg~lren4ejyIutBIj{gAoFMkKG=>@afr~Lk z@3iyETDnfZ8*|GM{J7ZA^ds0e~HNK_?hWqcl8TYcitG0bd2z(MCZLwv3Ymyo{ zea;WcETcw^&Ng;XnCgf3&;u^=SFE`;2Zb#0EstZHY3c{V`K3D|eBQxe-(1*_BpN(@ z%+`{LWvK>OY5*ZgjAG92yoi29vpAh_h1yGF1MNI=y{~qu~>2G(gIQFESxLFM`SJ6KbML`s{cP zJwH9jpkU4PBFPW^fp!4MbNG=7)LRod5~=2!#b7cnWbx+d(k^I!aC_4$pH$l=3BW28 zCE4)|4Im9Q4OvwsShX{OgN)SH@Z!@Pw@@GTFon+SWf#2!KPo~4a(XkEey<>?FEvhDL5APcF=I%GY8Ob zn>U#Oe@ME4v=`#Fg4_Q6vhC%^#=9n|z3&moe<*Q))kKNkwRi~G)0$_9I1mgkFO_tj zc+NFeT78*c)YOF#iL0Ndx<3F9KIUsakWfO6l*ctf{P)yMY9#H0bSwL;-0|pxY}ek| z%FctR;i_*OBxuFD=aGA}t^g+jbO1&n?tP{3#c&Nl1=LisApM^je~M;V#rXTq6*m4J zhwV{j%|Kd%AvT`|@Pv|%z9t4{F(U&M!}9t1$@yFu>P(py6s700A}FBb>XXGQfxZnH zTu6q%ZcKc=gTrZH?3V2qF_^ z3FZS9@qQsHK<$`IYBquwyCFE&AKFU;Tn#d$p7t4W`@hV#|Flu06QE+0jXT_5EnTtH zM==2-o)1UQ`}n072X-3k)mdZtP4wK(C1n>0_YO!6ODy+PGl9(k8!+OHrUpOri3c@( zI6`%G4~)z7>#sYsD^RaiRpwg!9rMFa#a_RbOyg(821qhTKw!%GfL8FN-H-riB+#jm zfm3_d`05UGdX-HUsq5Q-inEPXOx*w-C_v;3SF}jQXoHdvp1iW-KOLh~_C=&F%#~EE z)&+%L_DRy{{~$UMP^gU}`iX!&qkqikLvUEUGnRDNEZ|d&=NFOdtYJvj-;ZJ|tD>=o zGcnwqO*{8%&G9z?>kZUJ$ZQ4NI?x~T_LNgB_2%}>R)UbdFTB1({N(2*AzPXsa^Vu(>}MIe*2IMFB?r*N$L#<|~KM{GfWI?yTE`TJvPu;P>q}f$8Htf)^I!>OI7i z=M;wr=d?I>I1z8xGs`NwSC;kZ_?5vkpuw2!~;VlVCYi?ZNmTsR|T9R;HuGm2h0~^PFt>9#h6*Zyr`}S$)uO{ z0S0-FiREIxx3kS}*T`(r{3ptPkV2=1WK@Z!kTR{-y(aW(bD35`HfDm0fzGRO%kJ2z zr0tTNNK$8`S!9TeC3|dDaVGm#?M=*`ClAnWNB8d@H7mKg_l=f2nx;SW;b;V|P-3kU z!H6ok{ja0sW%7{;o@VQ&p;-CeBk?dPKxRPsY}5`*Hcyeyc-KOB8|^+{GXIIAv&&@W zOWL51E`DB1tJRO0_ls|pHXF(C6AwrtAwYq82D_MQp^But&S(6m%Mtx!YFRNc5-ohh zRd(1NYy5lBu#ojq-B*sQ%FNew_GZy`6(?Ttlc-d>tp(t;RRqWh40sGd`oQc6$RZHW zZ+7zBy*Q#aUCJu@jvshRE1>e1G=f`;tt}s~R+Z%b-W%7J?Yddz1Hmn*xan-U@cS*b?GgH zrgLBxgYrTffC!*7fh5T}yiQwnPht>t!g8YURQ=RKZP=@CA3xHR-D2^qgXgJfJMe!1 zOsGke?#kAD5wQg>O9GDkW`AYv&`x_6u7`(FMQON(dtKr3=Gqd@1G)vRcSQvy_Lr-} zoW3xRJ)ebo0aUee`3U6b0qq#94=jx_K!N;3I$?|R=-RpDNv)v8{ipr|etpT(*f;<2 z{SU#wC;@D;kS;UzoZ_;p)i28?GinN*^c$NVhoL7s)9BV)2ij;R#;VigAMs9pM@;?d zqgD@iH{A<(T4C0a0}vK`oWcU?hYZm8S@c02k0Bl&VjSBSD>L?O@3y)eX=ZA>DOyE0&iqM#I)C#xT^@|_8VP)E zv#4uig)UndLK)Tj@&L1dPpq*vm`S0UZoWiam`n+niGFsVb1|~-eTXX?kLI>oustG; zD}EQT72LelNzWzsNv_jE8Z=cn@TviC2Ar>5LM#D{Yy1kSV2kB#yMu4Hpsh~Bgm(Ts z+dg%n*EkcKOG>1>Z(@xu7I_oug2C`UW1x~BoxC5m@2Z*@*vmk7b~KGY4OqvRJ%huJ zukxS&*un6Y{zTiC?5_7~VB(%Jh#MC1&c(HNbQcM(*S03+v7hsvoEs&OfC*9u45p2+ z(L^ACQp3LG1MbCe`-mPgF)Ntqp025t9rmY=3B4b z^gCA=aC6SVAf5}LJ!Yrv4r8KLpV^FjY@Zz0-bb6Gqb>c0S+3-Q>ItUGg#dk^@qJ@K zT?)OoAC47iGNS@VTYtkU2#E;&hgAsx2U|%?K#oDFS4#s~R}(pR&Fm_UFi26ba?5tQ z$quF_5f3c;;nru_EjA7q&e}x`v(peQnn$p zDIo9%HHmT#|DK0L{k%HC;k^G-CGkTq!`fNv27X*+^Z^J{oD>ne0uIo<+e|s&nw~KIi1|Fyq z??OpB+6TZb)MqKDg8)GQs23npizDQSI8(fA_ih{i@%!l5uHcS4I?irOa=#+mNg|x4 zRbnMu>Ib)x0B8+}Wn#e?86HkFe^ayTXgsTR`&OjL^>pFC{W!gr*UV8b33IQ zs7;gvv>^MgjuGWwpm=6z6(Lx8uC)T1&YO@?`YY%?EWkwpuum+&?i5xhN!pd${UFNs z_1gxEzgT9CzBq_3SA>;Y?7k|>7dYy{@DD7~ z@#%b#`m}8rqeNCeV1D5@;RPijARLW=MJ^yA zwgVbdz%7MAGv{rdGF&3?AOJ_E3Ouzu_`jv^+QHi1h9rdDi?Ikz%&L+R@(Bv7uz5) z82xC@(rK5OSeOcGj3A}KeGEVfV_U=zKJtr(tMCX*O~kM3=w$Z}K;%zo={zxVs{Qik za4F!vgv!e+EHLw#L6#6nd42eZ3tLSD49KnY>Ff;U9jeR|yI4Sd0|po5Dbfg-VE?nv zuz4Re?pb|7MOCQ}E)-rJ6{-%ga2S=w2=EKjdFQoN51dDN^v^%miR~Q#G>#Yl($Pnw zjCMdYzQ|L}VG_;+-ZhVb*Io+L!rMXNme*ZaKgm((Fa(h)Y3vPZF%N`A7uPpTXiXVQLqWJ2&iDHB=bq{${W(c%|0N$TC zOGLs0VB5J+!=Z4of?KqUuIxv|mF@>__t0@I)5Pyj;YP{P7?I9BS@C`##ztNSlOYKh z_0=S4d12odlJB+2gfVb1OMeP)Vnl0a@s8b-F?Yu(r%G1amZxX0_Jqh*m;3TBQXRge zkRiR3lz2aq5@{zJ!BKnz32e|^kk8R^Bpxfz`Cny#2IM%KG~h2dH{ zzJIfVVBl|&pCVIynAzmjLP6KqxIKU9rJ?u$C87`7f7ABKZ>MC3y;SABuk93IlF-T7eHirn3Q0LdJ>s-u~1({5u;qKY4yuqMEHnFXhEK z%=zzurLkgvOBTPXZ};N&$MOeW6vC=T**S&1wk*^C&jKdc!P^0w9pIyAS5`NxBkdyv zWvn#+T+zXRM)JhtDsrb7fiV!eeQ!1QCug_RZJqDJDtNyYhyInUAKxTq-44d3$VD`b zzN%rq3BlEu#==_jG){_g8_X!E4?SSR2Qi*$gRGUGm5Ok{>d@SX55H(~EQDazno9IK z%B=WPcOAc&;Lak^7WXQu;Z@dSRl&@c`M++$kJnl8n^o}ZTv*HvVP>@DaCJ+)y$E&^ z)VV9;f-fRnU83)+azNM)Osv;OhDg+bW6*r*UrU200| zJpu1F{1lhDVEp2xR zQM5Q-*JI_{+imk5`J6cMR|UD$;QJZ<-wxI^;*-Fn3zS$TV7iOcb)CP(zmkzUS9_K5 zOJ4L`%0H*7AJxjkM#_H+TDwK=h+R#KqUG-;g9;MU#9Cc(KOayLvhsoa1(~!62jiZp zO>XX2jg?G!+RegwkC4ADYgo9f;jv>CfxlC(*9PG)MyI-dVUV4??HLgE=pT}(%|oA} z`1kr$jK@lCM;=LQ^z&zVs&Wr%FYlEfogj*eQg1D#=X*_kfV;0h==oWK*$}yhe!CCj z#%?|-v+bsJ3{gNmSuEwBpF&YYmPxmN^)c54GmkpxtFd5`|2Iv#FF+|ocmQWmZv-qs zQ3n(5T*FR5T?HnJNV{a;x#lWQs?%3&!Xn{A6Q4pxQk|?oLX^h zvp<`&oO5D`vM%SkvVl($05Ag}+(oTpfBL0j((AYdF{qu|nI$5WUbdK^wPVdYY?dBx z6!;)A{4)PmU<;>%U^mx|yTUPKD&ODS;@^1{al9FY?zyp2UNvWwO~%tj4!H{lqs@I{ zb#uxiA(Vmw<}HvKg$qQSR!47taLtv8bhhNkO~$-Rntt8^NGDEr-OBXe`-c|dUGO?~ zIVfod{x1dFM3`G|%vHj6=?dwKDzEIE;+OkQsFcxgkKKr7-`gv-leKVkUgeMY2S|Ma z`pyA@^-JV8kme89ZGJp};_+qap>cmHux3KUAm|<7CV)R&e@F5LdSpk%_3bk2+ zl%mO@>fi>|{Ck6|%{Rk1B78WYR--;9Negf*=lAmc$+SPH478Pi?D)cM*oiq?3!vCPh2nN2j-c}%0aB{{#h+u12U0*@8A zsBmGzf2@%7+MnV2*?viN%O?8VJ;%HrJ-9>1=rTosbQ(4`R^MRhV=tLZAm`U}j^}wp zV3ks{H9_yx<<~n5RfI>=3sGwRR)lfDjiit0gxCgvCLALhSGUzCOXd>hHzTI6lMb3p z&Dr)9$+Vp0btDo!7NZtOzDQ?|3ymh5pXsh3A)WB)Zf}e2Fz+PVL&bg7{$#7EEx(BY zi2OaD=pWn7e}$XGKiD2J98tdMSBBnA-F4w&b>xo+W1>kGrIok(;5LZY3yST+5)7>( zq0y0%HE-8lYD4=>!PR}gWbZCNlU4=J*TSal3U}M53$MHjQSl zo%UzUO|29d(|V6UH0Sn(YddsH74-*I>_s+*Gi6GLe(7N^{??o%mU*-bOWy%~;+12a z{F7{QdIE)u`UbThXgk2qM{CD#H@N1OZzV<=ocgug9@bhVXkv;8S@ z=rvGQflr+s;0jG(Rz|>84S5N?R&z>PMUK}nV?XkUKVGF!P)IO;#()+Qo^Wrt1=lOA z+s8N3EN@NdINw_CmlKTZ@CGQMpMZHULEf$?0v5cD9HIv^&4H1O^hqK)m%@*g~ar;7%-ev#9u`SBw9o5A9MkMN>vH{!U_2D6s0RW3u zx(Ikf?mQKDn)Gyb4H{0lX7dXs)BG?!E~Q^}YHv`gLr`(f`?}2KxkG;Tgr8I7<73w@4d+X=7r`DEU|Yxk}Zo2O;qj>i@JM~1F0{r>aQRTQfQ@jTIvby&M4GXGW&>)%m6kHmsa0O9oC zSPf0rfZ8Co*&Q+rd*EKSS+NtkKd=bO!_Siyjq0APk2SLD+HV~W#z#yqm;MU)Gj2p_ z$wz+~GcNV$_PMfM=c9w>?47EtPN$K#u_h%Edsav;41@GtZlOQ_(q~rwn|)+~tG!}( zI3LwU_^NCu;_n}ch-3-=Cmh=|!6V9_4;Lth?G?TF;HSqZjG6Q!bgW@qMR`v)w?%`& zwsKh5?pXWx(!{_Cv#`_c|ir)Q_e{KTf*T_X_1;fn6&CrRS9? zyjS*jCKwU?{FA^VBFn>OK=&dxZeSom^t#$DMtx5N6_W$#7sm8k2l6 z(+n=gp@~>RXK0Wi%qwq>-cEBF{RNkq_vft!O~%TGk83N953fckiWfx^YhF+XAc?XH z!HA(mMxP;{=&>ERRy3$l&h%)Dn1nYGg?s#k8Wkr+xY(N4G7Z`hebDA7*J|7>^d z)vf=#hWL468_D-TP)-7_0(3HS-A!PGSZFq{h-CTwgo%IRcq)scl`>c)xwCX9|Kzx> z&5C!8rNE0HbraBxpeF%tD^4F^0~YaHGDMGn$AEzM$2ov`xoVzn2OAtwI!@85k8UkL zx3TN**GO-2=U>iZkJB#N>G=HWVT-JW!q1uHRfjv%Oo+NR zFczSrN=WajoZh$*dXh321|KT2-QaWixBK57%cp7y{0ZZ~onFhvsR zh!TFkQ-~}AL`U|r+!MTM^U<49flmx%SoO)az)SbE-PJ)w zt@t}EeSF6j-8%aYDIxeL$&KjRtHEAwvaBOEBM@^X0hZHvYA|X}N07kk-A4xm2*R7Z z-MJ44!M%rAW^-WmH9Yzh!K&^qzM;Ed<$0MNqdU3#x!y|T)q?xuN=Y`V4>W?wL9xWD zlGXgRFX;t<4W8uB@n*GXnZ^eAkte)&0mwynr1c-E$c7$p7a5^yR6o;g8k@_e zw*xj>fXX%2P#ryF0=6aZfj1S>5;%f?Np#;1?)qhjtmaQ4zqK#_&CJ`QYx7bW`s?w0 zv~NPUMtA(E}MqEIsZgXsm5G06|J zmDzc@n1?SPqInBEnXNg`e~@aqe!EaVRx>+O45`0fvKCTW_-he*Uy?)vs2*4rO$k<2 za48Ystyp4EXWvs6$K`ALFbKQdAKcvd-6GNZh*>5m4qXM>DBQZ5BW<}?#;E$VM~k?4 zf1Nzt9?Afj9C_}|r>hk7z;Y8N6%fOm-OeHJ!vyX(3k}awe`m{XR8~J#+svCQ`kHWA=0b|vY z`AKG$>hzUaCw~VR<-)9il^|#)Txu7F1ggj+?4@Mh!l5GczuS1eto$^FX48dng zNKf#hSoz)L(zD{Wl5O4UgYV@p)pXZRQ>tS2XQP}?UmsPC@RBG4CmUddz+{@m4=@8{ z%6!kvN%qz*7!CeQ6E*kMozclN^|O;jQ51rHyM+~F#q@Wr0F+n&#vQKLW_n@*6h46- zHl0}#*chfI=#)f$*@eB1+lgu*nOJH}a+In>0-4m9!ic0lD%G83nGpYTIy^C`(N#?9 zV*lR4`M{}1{BCQ^#V}lhc+E!_KAU*qzAwBQMUNq`N+pZ6nYV@J|`YY0&E{SdvJP#0jW558$ z3C(W*n8e5^B)lDIg2!dnXNyj=YqQRK2|rI3r7YWj6JeW!tF*w03CvZ@hGG=uxzL=a z$z#>qr`ydbVN2PjI{PjL6vJ~7@}Ij3?;!y1AVB2_M1~Mx1ki*4QfUMM@AIj~D^f#l zt2vlhn%_^G=tk^VX1CjV|KzBrsdY`C-S>EW%XS6O7!CsFmiTEyZ~?0^!T_PG2rMXr zH>XV*9_NXwt53nt&P&FtzM^4mp)cMQxmj)u?)HB%X?ZHw3Ok@-ND z-$x`bU6%rPs#$>a=1<6ZI9)yl{|!K*?37hOJI{z6_ugtD6&`szv0L)s2-#}n|{svI$%|83f4 zi>jxZn)*l)S@4a$F0*r|Q?cB4s_8-T?Ni|vivoFpHrEh@qysH_x<_){s8WIopYY+@q9d)unq=LL>^qYZ3&KGBW$@{WmdY6NHg4ToF$3DNn(V27!eHt8FsD+Ijk*+0+*wF*@D z478@e5e)bFOx#lxIf{alq!H3dn&-WO&IeNuuk>eklUvW$St9ZZWwN6@PYt)sBdJ8h zuXiybTJRNZ=@1u+ERbjT-u~sI-cC@^zMyjt>oe0&+?p9zICi&WU)yguG=7e)EFOxM zIJMCN%GvLPwmX*ul)1vOsNOsIb;lD({cYM1)^xUP3(3&=XYTIt{fV}gQbZg<4{o5Q z`{gJwl0`5%#y!zyX2A{`tEh=F!-8Yi2#2@4l=Z|7wi1Uze^~`N#nYWS_9!l;Wl}{> z64%PV+BvU2mP2b7mRuCC6^Jh!i|IK^A7gx)Vti*ugpxJ@!yBgWoyzk~N6Df1O}n0M z<@BDdq_X=yz10u`j7$Pq8Dw<<~&}tl}~LMj{ru!-H*-FjxcG0M{&z( z^WSkz45-~%?*JY^e(#aI_fFkOj83(e-fiaz3#Ms-+SjHF##Gr()o06xu0`IM9Sb4) zv_@(fDSk`w8;!J1P2BSH zy|G8e4*s6JHne^i-{B}pgev0N=%Uj$^{k*v$YzF~0Pt6v6Z&u` z8NpBsVjs)kNk)F1lizqkn;Zq}EnDZX>cvOnpsXriD#QB5`@1c#fy8ZJdaLiV-g~H} zBKtvpK>qzLE7>)LJqlXtL*nr_v1v73xglIwpwvxBpIJ^iah;;BC;$U4Zt-c|8rerj zi;Cr}{Gv>D*_ZdG;zixxS2 zklgl9M3OL%=PBIl=PM~Hx1UL#&^}UIz#6a3)#>StBG_pvIDT5n0r9)UuPTe_}WaA&Vd6s^@Py=VATn^N$h)#FN~y1sH=n>z;tckp&A zS6p?L$wgBSFYC<)7zxC*zK=KQEZbovbK^(kP5K zBv!4YgWttR0JqzXr=;Ra)R@O69T#Yzzz2#~h4j_#)aQW&Yen>i`Q`+=$&MbRnkwu} zsqsvg6~SDAj2yKz|L@ZjfuihxpJt5*^sKkSO=v8_^6{pPtqNV0EHUf z%`-}$cJTzkJ(T8gvd!tbJ7?_vF58P=G4`$_bMwayrli!+t3%HR=Ead&8yuIJ^ZH*Z>AJw1i*t*w9X| za0oI{`@er~wQha={}&Eg^tZ#BcX6y##z;m!ST`!MVb;I@tYe;DB?<0x3GZCmvqMnf z34qGNpG3beB_aoO9q@4W?eJvSf=?y@{=JI(r*Si_>pn0O=)xNjH>C=`*R~1#Js$pwiL;T6Cg0 ziF;MZ-xCz9r;VWOu*rRr?}lz9EwqKlUY*Q}R&%{4e1P-xJFsTHlTS_)NxhD!gee`c z%AOkCAF}xW_g@3uA+rD5Q=ljZdkO-cA63U!E9_S-6KNz*=8B;oG5C~%s>kDI)Yij+ zR03D)j>(3;0%C!LOhM-w3AJLZ8QSjI$*SpS=B|KkiW_a7VF+bEMHfl%q zV+n3c#`UnhC0U{c@C`E$P?6pcHAHkypLmaHBB8Sa1pOG0R zlHCsb@r!(9S-*NpVs)!>c0}D;UB|k7@ljg6*9Cf)fc?|z1;6iK;?#5Bn19>?)+qCS zroudp2RwU?xc8UJr9hV z!`*eEt0PYM-0QW0%#eztie-Aeu#rqm>{a_}82Rcvx`jGuC$PocKTR895-acP(kmk2 z?s91)b#(o6pQ?8waJTpm*}U_+86(5zrjTJc*mqv^F0}x7;9{|BiM{^xtGv7_CmJo0yiZR7-4frWB1xkTF4;S7=^aQ@=*YVwU!wR zDm#iSJ9~e;F{!c9E%UXh ztja_g@nq1Yr8rL*{n!xU+tf0H*C5u5%(5;b0ra@Edze#=(=lN#AeY;PhS*0_a?v3 z4~%CKQ>TVwH?-gh$>k2`4t=YKyF z21e-x;ZWvEbns2rNLT)e4^h{a_LG(IhAxdFs+R}C!sP2jE8WA*B95Sv^8_09*EF82 z`K5DvN*R(!kjp$%e0BEocu{OD1>TH>#L`fhv@eEDN&LbTajJeFOX+Br0PJ&3Q`cL7 zXe;;|d3I=&l_USzfxt>s@HP$G^>X3_qA5lvORQ(owkR}Au}-uW{8oS0jRo}J4mZ6` z+t>m?CBAvT5`0GmUD{cjw2b!TG;Bywd#T1~ehm7#RffB>R+0zndadSnEb449 z?*!Tq(T{RZ8*N{p_BxFC1c5?IdUeFzyOXUlDamsmiFB$_nA~&G^9Ig}c-SBKBS*Uq zfcZO8IKETzK9gl*e5n~eUSHZyt1YjvG~NDqbcmRlsKzk@5iYD;pJdHzJshy`$8RUywxOT^hrg$DPe1I!`A)~RH1XMu-LtnN zH=XA-tihhsaW9P`g&ri^cQ8)`ujS19D%oD?vuu2BquHOFEqq?uJ0pLQG_uI67uUSU zr56kjgJG=Cm*IgNawrfb+4E||$h$RJu149`NEYbpx?Ep z-{ZPH7j;$o?FNc?|0zJSVJG$G(o7^6{>Ah9Y;+<)M`En-*SyP@81?Q#-^T}?)hp|C z!i!~O2CL2E9ek_Gep`;HFtIvEJ8cY*N3W-gg(3Gw^9mm=w45y?20_z5uQmRxb|=yZ zs@o7f{ZYX=moRg6qFA)Iq&PS#tvS|= zzbaRbvf~f29)7XK&v(mEWn?Ss_TOO=aVjK*NXlO!gYF=*sKjEkKOT26U}LoVS6JH- z(p9PZ1&p0zM3D!a8FM5)Y4dQIU`}3wa(%hVujM-ZJ`vm23#f}4dC`CnUt3|SVlr5s z*WM!(lH`_!CwMY|m(5M*gnE?L2I71gIL?s48uYJ(D`gDCXH&VqBWEsRE&Zn3!2!qO zzc?}zy@)?te3VXZ`&eL`KO#FNQjU8Lu~0{Dn-9$IbS2@*SJXmxV!Bi?3k|fUAo1%7pqL>{u<)By};p}Kra$Pnl^r7_h)QE6d zsCtXnddM&uEoY!0XrpkT|>7z>B8*9U(hyYV-|h3{s}}ZH2NDDLkL0 z3y<2HuCd5-^Zxm!=bI$p*#>cY+SY4v8Zy$ia#!29l6@B43nQp#jWx)sl(}x97T?br z!i)DhKGd)qGhBNuezHBW_IO!P@3`M2A13j^+oT8XJn;Z{tgGs!7)M*qr|Wf!E&Ddd z+_Jx+!vWb&Dv!-HwKq>!=sgYGrL#WY4NfwaIOTO+i&P<>v3qsNLD_9)ds4eoR(ea< zRQ`QYjiq}!P$McjfwXVZiTO^cDsI1tx?WNRnrmjz`b|1Kb;c3FtNr0}7ts5zL6hCG zJV94`00)EG^Ec~Qm&t4BBC&n1&1}b+4Jv!@?#vTQ%2w>>%wOT{`^4-t;KR!7@;V_$s0^^#)?KM>1T_ zlxN)f7I_f1)DU+5Ckxx7uoswc>V|zfOkonhre)N0lB=h~;o>Qt%H(Xjg>Gw^+HyTQ zwsj1{mTEU4*QtW=K?fM&y8ix$SpY&Z7#-ccRjPf|t;0@@_tbvIS;v~+#8Bmf?Mc5> zdH=oZjrJ8yz3ViPTy8W2wQJR21+b(o3=+NTHAU@vaN%+TQMM8{Kv>DlMP0bTFZoPm zMaC+RC#YGfxL9qn^r8KU7T2-zfQ8!O2hi`!l0sP zv}O5=-d7h;euXl>PJC%h=Pt;^u}*BejbM7VncC4$Qau!ONLTk37x{Tc%Q>)P201F) zI?Xt)oT5Iu-#EcTx4dh<4Q5g$WqQ`by3SirI4@8b2P+f|Xe ztBL*ADAITTsu@lgJC|r%AAwMOrB#1@Ze=}eiUsM}N{rTG4r-VdFNCe#ZoLisDR+m* zPSBLMhkGGqYTm<38B0!)Yr$82{)S7rz?#D2YB2@20zqn4;khsEKKaVo=vyf7qa5{2 z*2-z;M0B&US-v-M$=NFwIzZNPAO7aZ@geRyPVSuh)0Xn3mYyiowr zt|T)x|MDK6OP=wjq)5EVgh^<=k7aQ*eDEUs3Z%*t#96w+`|sH9Y}f1H(_80D90>0= z-u&&~CPy(tHaI-Mh6ye*37IZ?a6(;?+p>`oCrpoIMfv%Eup z_&!ATV=n7aiD=7kiChZm_bo})K!1M967tuc+1BuH0slJa{AXXrJ?OnFYm`y#W^2@k z&9P$S_g$AJRmnP!lbGOuosuph&F`JCS~-31GZWx@5pFBdxMu`S1n$J-HgQxRjPpwu z8RQ4)Hn&ooV%p0`v)a5mIoWOmt9p(_YaaX5V%P-{xDeTcsiAt=TXX6V=goO6F zeJ%Sa0;h^9{_Z!N0wLUt)Nn`Dx8fKi+Wr<>qc7!RsW#I;wg9gI{A{-M2NHje zrFDXB@hVBanrMRz=nvShnhehr^>QtW+n3OW30iBq6HSc2W$4xFo`kcSXsw-6_V^L z09;H2h#bd#%F5XTMpFtX9qLO}fZ4Fr%{M!g`>M1D63kQOb{*AqkhhkfN7KcGT8L^B zKBG3ps#TPUsn=#6G<6m@mS}pP9d=Q9OCEG(P%6*~-w2PYWe-Z(CpMNi9vfh|+@H{h zr9B+*FO9Ao{1-0>+(`kxVW*I0ceX31$rYiTnSZzQovPd#Zagz++T5GC%pkgt{05b%sf}23?4Vug*r!s*Zw@QT<-jQPTr$OaGzKh$1F99{=CqNU+eJx_j6B78c%^@R?~`cM6oFuWZ-mG0FzkF zz>dW%NDJXQ0%o91qL4IyFZZ(pKL2aUmv`0v29Vo4e}X$pYL=v=Q=X%qr>quj7$HI2 zzuAZAENpQbt;k{nZP$s6;db9ra#~OYW zw7ndCc!a~)Vvd?D)LSy%x{wKU-006%q|PxvJyr^@UQV#0PqM8hRoAtX7?%!bY5PVY zpbSd1Z>mKYVuMoa8%QC#n&%q2cK)7ToovWOGA}?alB<}}o>jw_pSFlgv|YwI8q&Gz z4dGI*joO94Jl6NCVG>XCJFmg-qpinj?$d|mNu!B2;_as#uc-z^S|mS&S1RYwdo(r* zcarEiMyM}6V_iwGf)$h)hF9jII;r4PIvYaUWHl@L0UC~v=LSBoyFAfjM+te1xQ~~A zBni=DbFNMb_@EdoqJQi;eitSyb>;+p>-QHx*bZc33avJi_J}yyWr3l;3U2&~{&zpr zNLhOJ)mA2@wY^I8G5YfaS3m3wk4jiGe6%j3uDi5fk{sE3KP!3hscpHoeArnlYku2L zd_V;$=&%FbQRHfWMtQ>DZ#6T)g)S`@JEQ6kLfBKNbQjIKnk2Jn_**-R^~0dEn5n2o zS;s{SpY*)bWeJxD{H^RO`~Iyx1%|am%1Q4<@~}$R1xtT@R55QE)p`g(pJ=KV-U>S1 zF9WwzIIM7T>sa74mc-x4 z;M#22qxJ~}g9P}ZU4bcwpCGeWOfe>wmx7Y3%}5nRP_MT*38;}|FU+NFMEUAr*eDeF zd?cvwvmvc`v|pC0%{0EHD{CuS zAk?cGzZ3%aDYR2_DMONN1Y8O?J|E@WBhc9@i)ao~NqVgofQCx`Yi?xuCH80lV)YA8 zO`Y;_=;q1<@Sult-T3Q0PNrR$%vd#EJfTz`din2x8vsKWKlLnIe6cxq7wET4{xh1F z@zB2Uwl4m^si+AQ_Z)xt*z{c-Q9cgi zzhCC3oGfZeuztNbMwk9Q?yLu8Qesst8cTK zeWi9udIygj6?aV{|F;hrnggu7#p0gGCQNRt8>ueXsFW~r?&O({UAa}O5=+ZLa&T7T zIQnnR73@oB%l+?NnVy|&6Xu3npZjH&-{5s< z4oE(zgeE41>7>GeX6W$tZ{%sfu_*r^V{srAsk7>){$uJp% zH{JqVu9wJuqu{46v2NI2CSc)%N{XpWjpB>{XA9zyi^jY7QRh^x1h`WXbW$>e{4F)g zIqd+(fC>wwr@)0mgC-#1z<=gRfb^^Lu=&|IB&(HQ_0ioFpAG|eMz@*J@DaB{Spq|@yps^?Th@YX9tT8`YTG=v`SspHi@n!pp=lPnse3gbj8o3F zs82*``0m(!r%H?y^_LfqgL7n!8%I?Al^N&Z6dCva2ESx11j6!?W3_UuiIbfm47g6C z%WapnY5TYOZkfwfqz8-|dBcmX_uW2~538$8eX3XD*9t&P8X+BQs$>O6)e&hO_0pib#oeIEq9dK2-=>#xPP%2{IInv>P-7vC|<7Z|ir)#&ER67mlF7bRe5OeD~ZfY85#g{34>lMAx%_S386ul~|P(B7Vyq0ASlv!p;#hCKpPOxwsUWszf zP*QR*Q40TF4(r8wZ;tJ3y|zii3@x1YDU%;hcY6fqwnjtbwuWw6C=UO%=Wf$l;4l5U zGGIOm8hyR4NZcof@7`L>8(`da{|sAj%#p&^3s@})fhn{B7>xOWk(KWQdGCr%x0Oul z{=^S|zY;1#1?o<51=)C|(H^BAEG5EHIfp-roLfFs=k^>Y4@C`7!S7jE~Gdl=Kd(BgYs0P&jg%osg->2VC=AM>c#HH z*j8WfVv>(gM;*w>H(c03Xrlm@d~~)-*RyK438|5@efm?}KJ8+qgmGhK?8Ldt;WmcbiFM(CrisXtxbvy*+&mmD7ibBaoq? z9&FS^PcNy*C$Lb3dO9R3BW!^7^=#wOhny%MqihN>lkmdy+wI>iGvGL}M%CQ}g(nnV zZJ(9{9@0#``o7S1bh=%;bJ(UK53>z6oRG;XV(lcYxp<=R^bXgCJBxdg+ts%tM%Lnc z4rZLMdVHMG`4=4<&NUpnNjY(#3!1eEwp!iJ&yaOGEr3BI|JH=T?vxuQNCZFzu5ZZM zDBz#lt5+=hg*Vq;(szwFxBfZkVF9H|jE;?f^%LLHXaTEgoUZJy12-DaP+ZQFDThu) z=v<{B_#h(enJSNG%aOhB1Dm1u0f7KG+ny7QrC1(5dQ{(ee8a<@D zYR0z8aI>jG1sMP03CRQw^F?$pYt`JBiH^YE^EFePpv4p5SFI4YTd1CgoN>s2Z!|nn z*L;)LT70yhW(2j-lGu)XzQ8{)42Z8@FD@$t05HeSk-Z2nNt8`V5O0#C;o#!=OjcO) zre}FOUgaybf!lVm%9NVTX^kkxkHY$#LMf7NYUW=^HRD41#mTmLSl;M?q+-%-FUVN9R+qL`gPzb9|qg*Or7r*Bu+krdNKuvl)zEnu50gyY~Y{yA~Rk zF96=^cdL~#=mnuFODbt9Xk*msd#%s*cC7W^gWe?f=dpq1l8*r!UTnXgffrI zp!p1-XHyM|h!PZT92deDVb{u55$8xPpxj~aLv=X+X@-^qDW0h;o%Iz5<+`c|O*v)X zn|irQaJ>=frAfSHYFc*nv5Q&!U&_h1UDG$fxCBi5vG31jXx-Y}1y7!W33Os}32!<>uy# zTO||tUUb~kA;X3oj4gGv69mtW^+cKD_t9&t%|Z>l%KAE% z%%mNNSB}(Bs}*Z|h#;@#@a`4Im^`ZIEd~Cz(!OzqRZ*Qfm}W>?kmWb3!@TQYn%ix~ z?~r|uVs!Zko+Kpj%dh~hm;!n(`&q9O zi(z4BY221hkZYTsIOB^P_SKv;chl=vzh`(GyxruD1Z4mu<> z4%b!{_nTu|a9<{^R`kAFGm$(`>$1SCL_LqN~qr{U)*Lrv4&2fk+VaZU zJ!U!mCNgD7taysxY%5~>>(yGNGYSKnF{6s-`DXsHfgcti`0f`&Nqo+G(H8`Mtm;$a7F?WwFZ1Mqh zrS0TLY`33HTozbuXi$JNHF^Jhqp0&=Qiax|=7D-MVhWN1%TxQ0%2bn|N<;thCE7*- zs)g2x3=A54!Qfpd5yxTp_EF4~YlD_1J2e&N4kz5}E(zC$>$I zSI$xWnJx(YwTY^$P$T27)sviG!S9FX3UZ;3RmjWR7!*I$1bT+1BTi-^gFIx;>OtPG zU^r-~Gl~tFtWH)I!KE^C>ql~Pwc?~hNXyBVs}=@!yT8<#4v2|9qWq z;ORC|Z@;#D(YXxH4wTkR65(u?v=%ReWRIRsv*7BMMBX1w?F8C2cF7rp$AhdEWK#=E(t&h0vm-R;Zu17tFe1sx#$-?EX`Dyqbk zYb{1HCYle^>!$zRS&q>uBiyZQkhkMZ8RQSI19Ug<1DZ42P=^;uJ^o-*yz`f9I@_oQ zB|AboVJsSb8ehOY4y#n>fgbZ;Pdo=M8q zpO!JES(=NdcA3iYRr-wMRiKXnTw%Ov0yCCuEt?^+gg5B*Hq_-SAFF$x-+nv4k<4CW z9vq}b(IyQZV49&3AIqQ=Q2vI&^L&TZP8t`E%R1U@+9WNmhU-V$#*N=cvy)%)@#Gg|U%HM}ANSNRvu<({)KGYId(=rla|+@B&#F@YhddX+A86dlXwnI8 zxY1i2Z5T5Xy@n=X1i@DyGra&GnyOl zwhE(thDPicFY6>L(1|1q10kHYJk|l32DfMYN)@rLL6=jj$z0EyKU6m6-;dlw_A{uj zex*SdxPfEt)%|zHIx}5Q^jfba@ZnY&{u$vZm%QJ@7UaO|mWRRHcE}VD``;?$Y^%RZ z!Xy}7Msn5@xm+eJ9t1>_>f1!Y>$;x)OEDzn&-vB{F(uNtn}k{}yAk`D4K_%e`)zv516mEee@rlI{xC!!_`!#<`F~rY zT&8FeoV7WIxA}7{pK-ez-Tn_LG&QUPMhfNZ7;tfB#E}#}Kcp&C_URYt6Ee z;%{`!(LMz~Ro9Fm>6nlSdpYrucaI;PN2kdL+vK|A@4H9Dri1d*wrtvSf(Btr>wBhc zcIfvw!JbfO@@agEIlXa*|!{DMzaMXV>WYDzdBH4gL-k0+`WspI^Xvqm=ro~c|5wd+ywOjJS}>s;YMEvp$T|e zOQ3ij%B66N9fAkRNr?GasctmAl(lKn2zcdn4z!BC_6D{}Vf^!7&)>wnsnXvz{cE?v z`5QyTarJ$HrOLrd7nLY=7r-Bb;I#Ta3(F>Rm_9bdNXmO!bqkKBU~UzkE8@@TM>g%% zNxtL`+W=As)N23h@nNFb&Y)HsK&=4{pE3a8{-#e>4a?xkJx~JoX*_QKbTuP4g^0fh&b4+#RDyV7U*20?H86P0q%l+a8LSFjr7H6N&C` zjtutcS#q9grxK~K5(^+=&jMJ;9(r9I505PVSKc>cvxBs(Yaq%=8jQLBkE_jlk3_6F z-s2l?<9i`dgiH@uq}XERUk5sp4<)Hwfz7i14BX3)?R znhOj7jqi)g54&WOFh;M`^M;M*Lxtl=+=4~^Juu|NR(QcRKdN(YIcWKmm)bJH|Hvj2 zHOu1)n}Co^6#Xb%>oUsC@pXms$GaOSAeC$i-d@|`rzFFlUh_vN$S|>E_Adk=7Y`Zc z_K9F(@rD7UKhu4F15DP!)`(*hxogJdw;=*x!lU;`9smRSufoT_{**gx$@$M1$K&hN z?O&`@L0`vzzHJ7p*#7!AIilmYAC>o*5F|{0`+RD#PpsTri2p1pgT|=UoDRde`Ali2 zmYwfp6t8V<4!A!2RVo!u$w2bWw{T|}tP)rbsy_b-?tPnY`i~WMQR1l}U*IrfSxHXT zxu@Vd|2JE5jx))!TyWgIy3N{P;K#ir%vLNzx5sA!4!s83S2{6wAK=GGNQMsNLib^M z1GDj60@=J14;~Q4)k^+VkH&ww&%4aj7!T+_h}@6V~(cdk@Ly{EJ0g5OR8&L2R9ULQqC&j zzK4_vCr5#iqd;GD4fft%E4i%1Y*ID(doFn0 zI_^~3uQyd#Z!=BmbbUJrULZuH(mlo*rx-T26DEN+h6Xj-7mGqB<;n`P2d;&jy)*Owb=EmfyxJ-loK4d zUDg3~h&%dSuZNrS$P{8ZhNj*&cwhZYPirig34Z(TQH-By>2G})l9>|;u~k9;C@X7N z9=7r24O`lOiRdrTsa$mBPW?l+ z&IG9KN3=MhDwi(irX=psQeeyh;jd&)#E-c2Y8$cC<(?EuF&U@0f%kGJz&lSC5iNK` z0t+~7%B|3vPd=KY*4oP%QeoMW$ppL#Od{xiV4TV{Uw^POnIWAtK^&EYHxg%WOj9Kbq3lgEYr<~=8V`u+f9=bt3|XBX&keFiSr;w zd@HQ>XPZX`OD{$CFvz51<`x;JCnM&%=1+)q-}k&)eO8cQ)PlC2;k;4e8 znh}GL1++kY@R9o`rS#8BpGr?m7R%}8P#)C)AYg!yy|N+}e?aH=T|X?MGPOjIPQ3$o zI27)VBQ}Vm6l-_{9GrEVf9rS4Vg@5D2Md|-F#`EAm+YZL z(eRQnjg7qlv4ZBuV2N$DNmjmTM+D>zb9g-F)4l1C)-+ii$dm=ucnE(u zt*F_u+wzDxn~H%X4||9aPrLkyVK?Sd%2NR>>l+sr2GmNAho+6XZ$5Gr2eXc zSD8u^@~XBPln1fxz9ahzQ<7ffZG^FE-tgPeO)A$pALMwA$*=XA+!x!Biw;QccCDja zX55$rc&9-CsCH1~B2w`CRDZUN6#2TLw6QW(X=@3V?faM>i3fXpC*- zaV!TTJTF{i;1M11g{(V=;@^C>asmE#J5yXYyu%L{IJl1ywP&g?q64-c0`UL|lDsR+ z;LevwqaSXd@&?nlQz^1C2tvOfIhcMSWF%w$XK+osUps5j|8{3)&9#V%$wro6*K@O2 zJL*|zn?X{8&nl=o}W_DRBV2U=Et`U-_x^lKKl-Ti9WxG}pumWF#`t4ve zsbJvVW>B%z$a9oC1`vKs?PcL?#+L+YD( zl>Vw;Kmp9)6XKFXJ~aq%7}Z1UeO1IpC@z07V4Da7m=QuYh@3X_qWd`p1;3cRava`k zeg%2(2P{SP31R(fzt_b1JB`{25MP5hZzB-3LF7i<1&oCCGtC55=ekVI{LE%AH;VTw zzR*2$Ulc2B&?o14wrm=?!_)J%jQQUJe|jMUNAH)SJAYyZ%9k+MCw_1uE*HO(MiTv{ zV8RD``p_&5&Kvx4;TvsNHh^w;OWgMUksKieg8ArY>OA%h12$4R;hA_h_20P+Xp1UA zvDEc_A1Dd?zj*gW(ug6Vf?4kO(ogR2BmM>}LZEz&Dkn?25nNWIoUZaq#2-pq?gbQI z@hav!OiH8zbo2#C9b3CQq-~Am5kCG_o8{v42`gA#rE__=dWo#KfV9lu&&eGwWXeTX zoUW;={ab!BGVo$MSM!_V-R@Y!-Uo{JP4G*!3mC zbJTo$*!Y`w0`C2={Gvr&h z9vtviz1_g>-xDN(HE9(#p$lDb@o1-3|IvpD=>WfwsmmY4o5^8=vl{>5kGr6V>nK2R zhu)9hT^JAJHyX=wqu|wW#-}AF70+-(gK(a5oH2;W+k@^bV@qWB zR8H%MgjUJ$RD0Q);D9d$Cr@w#WChYdBfu>7_hNmm8+_UZRKVJ?gm$yD+I%9r_%a4?S!0|NM>4vQYbg|A_JSLRN`O1cV z1IgGrodEq-0cUf96wbPEF|mU&7~sRFMJ{D%y*}f>c(wb|7tr=~=d)Oxvt)ry5P>mr z?KfAc#J2?rHn=0ZTlhm3jKihQh{x`i5~zf8UfN$ zgS>ONfRdVl$E8^xAPbRln}3g58d6b|H${N`*8vc~q;(~dE?hWW?SS>@e4}KgFHQS? zk{jbFhef|LJgbCCoh0#9!gIPW^L;#ohG5!EFVSqTu%e{q!Phs*Od}t`S)$6kN{E)}Uh|YoRg0y*t^#=kU;Pkk}?hr;xDtfP`?{0wS=n}t5pdVT4 z5_5gLE4(+|ZM27j9#$hr>=Qy)AJ($vxs1A38slNXKX{v}CfPqD3{d_R?YbKMsIcB_PnI zUY#^>=7l|z^P6S~h?yi%$Qp%uMbCX~_8WPm43inI4K}rCslb5!Wg6j!t}&w0jLZvKT9&l~{k`U+tO0s4TL{gG! zj%pUadWU1U%dA(WdUs3rLp(u{U}h}>VJ!j>i18m+VN5lhhn3GkU$8BQ{{s}zHP|ko z9w7l@R;0Gzx3N^h3`>2{LJV-i4ZlH^b$uuM{l`p7i~!JI|B^{yr6K5n>EEXlegBGsepF8baldr zuWRfCCRTLCgZn`R?gztv_oFll@*ZUd7vzbD$lkh9wro4EY1ATBizrV-*A%kX-Be3+uthhGMp)V7ZMuS;*%L#G4^W&WhA#8x@l~22L#<)V&8PP?Y65aRtLjy!i1Imc88zkx9Pcm zt7?Z^vz;GruVFsA7gs3+D390FA#fz7*FkatuE-Qpv9e)lAYvICJENlCOR%Z{|! z+nb{i8xVV9jhQ!P3sRv-8AvQJ>kWn29Oq)bhqN1q9QkZ!7Aa`6iE05oUzrS(?JqP$ z%*HJCE77JV=YLex39?E8;guwZhqK>PL^gsS*isw<62XRdXCrBsoI(8kqDt-E70+K` zVTY!iPkiki$`B@D3?ltpezI0h9{8fkf(wHr+Krc^JcL; zmhl}KWw``B3XGmA6<Y<@#0&1;< zLyqb}Skn@3v4i&7!54S-^(wQK>7csx4q<9KJeo=U;LuC-LYo{?!Qj3_j=V0o|Sd!gks zcu-^$mL?ju&2_^hQ^4%><@(GL9UNA+(lCQ=`e8hD{P}|(W8J3$h`%-SHi4-IzZwnB z)zaMII@cZ%U4CkP{}S3Tpapd)u{DO2(DBrj$Jr)bdivQMc*e|)_PmRb#}561osU2t zwrl=j?a!u8vK;W{REq19<>&b!?RQA_ppa%iGTrqa3PE{K8;1!(fJETh++^9-+qd9O z#6?zu@;R5>n%;Iqz$Wf~>@hq@k&6RMO0DJV)dEiC104%zteEm4x9(j^G&(EZJ>|B#Z-X4IapwxzS^kE?yiot*r( zID{BplEPE~oMq+egoaAlzlm(*xlJPUmGyr~7A-o-V*EHLtS&bpRDB9tW*jjM%U>R! zXS7-X4=^JkP0YAc8d4u*h+WZn8wkJZ`5h1 z;b&PG*R*nS=+O^K+6&bNKX_JIY4!N{S$us7x+REK47@?#Xq=}I$FpiKWsy@N0ISBw z5*1_gkalMF<4YhY2hH%-)BeM-lRunHUo(Y^ypxlAsG8R;Zzn|D?@yO!_ju$hKev=R zQS$%m>AJ(IaKm~-Ww$ll}Nl)aT5A|%<4JV4d@LUf7Jt!CRdfpkt$(%nbuI$hx5iy!(GV1qD z&(>u5C>!(=Kv_hYZ-5N^`|f*pEX4oQ_&x;Bo=nwTOM6T-Zw(SVCOT~~gmtX4^mVLw zB1(j4B@8gZ`c_}OT5c9$;oo$fORmN+R2>6!l2wol&L#7}wnPF@+{g!!@;`PvB_*_rY zO-rx^Dc1<|c&c2?sf~SlYy5Q33!t~=WMLK?bJikWYm=fXqbX4XtTXDM82iADG z4&NKwRFG%*dI;oq_Z2ca??o9tBTrIVUyghM<1{#J=8ULL?Z$;I3g;cpuRWyJ#1gH- zm;wK!iG4Pybs;)i0+kIj0o7w0p9Wg*8T`0YRF)aMlfs}?A^`7X6RBO}z#bZ!jpNc5 zulfQL^4~Hu^5U^}`^wcd)qq=Ef<1M%d2@j8cXvQ)Yuy%1FF~q3^aFs(O$S#2GrN&A4!J`wnYugGH+@56eONJb#?!>e z1gq8S3If`nfFZW3kR0{}fZ4{PN{`F_)m6Ng+Q26h{jZ3N^+wU@1xsJL&BFzXS+msU zW%|||e48Ln4Ebfb40x1{Z#)T}U$8QR$Fvdc!M0CiPWCFFNsid0>Zapl;Vc{~q@kpM zThKdsI5or6Hc^9Wq3RlW(q&msQUI2#v+^k*@PJ4G64OfYUTyt;H+x=Df`xbZ!*+gR z4CpFw+>J+Ye(qj@P`gf0=-8ci`6fRCmJ8S1lhNu;+z<$-`RF8 zD6TRv?VEhq3yNo-tUN@U-P9PHityRLz4!BR*?L?~VbHbQ>ZGi2{6yHXZHP-iPBM9T=e|$m!%uWS3Dmkg_4Ao=Nof7dM2_6;G8VeEX*Kl%5LfgXC2W0W zCaxYE2KQ_05}8Zw1nSJ^_>CBq1oO-Xa3;6DkEU!L9duR;TXv53%?oscC+pMRpDoM* zK#H-@&4hSed(^qw(o&OYF6?~QxQaPWn!ATb*{S(68SjG}g1DqnmLscC5Yr9Z`Do+F zCfu*hP>}HYYsm|hW^qzuw}1H>2qhrsVO|*p2hQT<*h1CFFmAB{sJ8%4+HFZ>)@Bf9 zEC|-Ut=3$|;REqXzTt8)q^)9XWW0*8-qzgA1xUn?)@iHPhr@J>( zQXj|DB&_`VQ8D~ub%Y$)sOiJU84oind!CyV9CK$}smG)nMu}CVSp(frKso-iNP9-f z$Uob=)M~=D*PWusN=Y~WGXShdwzA7)d~cW7VRW)lzDWXmdz>lY?fevJ8VYW>rjZaO zH$eWa`u}hMn-VUXPdK;}w64=4?v{i?p1yFl9CrV+vXbJmsI!06Gi?l$ZnD3DzL^d~NkMc~68A-+?#5N-*MmmQ z+a`Ag>6G=Y#eNpauN;O|l%eaNsg^-DCVvLV2N&RqG3hj=l7MGOYaNsshsXAucs89Z z*Hn)u=QD`*iiP%Cli4|MMcFa~M4q&ie*kY)7j;zM-TsUrALln7ib1twq$l-ZyOY6| zFUZES&H_(S92MI&8xl6}6QRD(xXi6FtggjfEEvxB_BMBY(tRQ|RRzvA-<`gX5oYRr&p`)wLvI^PoEV+j2=K zO+sPlP`I@JS8dPHpfFOiG6vkm^#zEU2XyC>wYXbxGzY8}m{?tM$3F9+@oA9Xc2FN+ zZ}0+OzA|v%wcCK~wfyydVj1L{A-3u5Yv=l>fKBEi!7p2cF<;a7Va_tqvBnDkSzH~` z8V;)6ps*e&ISSoO7|3RV|6@@B{#B+ z69+jjnF1LB1!hdcX6Z6j7QF}RF6n;&&5#I6H2(C`v*DoLy0d!49ytb-HNVLz>^3uT zwVWxNQqLBqVz87%eQG z!<_&PQ}Ha&l8l_rek(N=?cEg95^{5E<#&OE`&~my%W)dHx({K3!6!(i` z>Dsp2Q)%(lhlWo?3?H=vevpUxE>a3DGYxY9&-i$`SR{&-q3(f@ckh4e0OCCm;FwIH z6qlU!B%T7W1%Bl$sRrx{gP#)>+z;V*Sdk4sYvY@?Yn#G_B~{UuK)CNakkSrl@iu7BjSY?M)0Y_8M*_~5Ocpo`jd(JgVW1+T;MgWQ) zd1Xlhw?NuF0SPYmk+~P|?P8BHAZaCRby%I;G@8Y8FKW#=k=gV4j$NA?s8s-N(Uwtk z+XFysRC+R`P~AWz=>gGvnePEbg5%fwEFcFtOKts35bh5AN{*X07QU-EsVAeLc5^2a zwo{T&@>LW_VyVbTCLxu>Mk0YJIrKg*`)X-oI<PzK{c|QS>UhF> z-6DU1!h-@`_ik-06MiTu<2U&tEU2K*=s~i$v0AsN-v_XhY_S4zi3|5nnqj@16+jO{ zJ~TYQ_(M%#ZxOwI6Bgp2K=ES3B%tu=d*jusgx7f-rs%MI>n{?_fYl@4f59wc2_(TEbdsqQYRxue=3k!HrRZZbeAi|h|)Q*e-jGS!|fGo#|Gg`kQ_ zGcViGHst;{na1PG`jWopE8c|FJSBM3S=9r4xs<;S3!eiE?$&1}7to|zfeV~^>|>cv zZW}tF|V` zAyu)NPgn3N>=6+EDGPC=tMjY&$$k6qq4ooF^BucQ5ZwP86EPUm1>7R_6Z%c)XZnDF zMcU>M%WZ88Zv2ek9?*Z|XG{MLP$4t;dZHHKR-QQLI_nT9dr9s8$5+xMifOp^luPd!g~{2b)=-)Hk`O9795qv=$78b@VqTnMZho}+ z7SVch1L1@DwCTS+2IGL?|ofq}`{Py!;D4}n`%l}JC@Jsd$YZ0%Qk*}%&W@sIqO4FjCeOwZpphl8Wey|gm;Qesp31(KNHK%V zmmaA(-$}u(alET%8T<$%;dx2*|Kx)tC&2^pbH-No(V&}oA_;|xr}{GWi(0)pLuK-c z%{A-ep9p81HAS|0zZL(&{gL;~!^fG8$!*kqr<63m9RyhJB;IS*gh>e{d!dn^e6H%2 z;B>?^3%;fx#E}Q=S?-31);+s3lBqK}h3IsTd{#?vNpQ5;i&3j%vYGdg0!igJX6AVEwDO ziAE%vPQKCb{*@9tnhpKC^k(qUj(!j8hKaww(4EBo^DIfqa>Sjwtrg?-idwtYsNpLk z>35c+xBGd7_707lxo_a?2UpE(*%qO|RJ0O$oBocTpCCYBZyMY6z(*dJ6_>0oxMs_f zi76B<0=k{Gm!k{*fDNNM$#voVt+CI5h2fM{E>;G@(MJCSd2~1q-dJ|mWTMWSuksbI zhvy$`H=TU2Ke`%yd5olRP*9(Expae1DD1=JG8 zGO7OMPk#Jg>{`V<;|r3dhW?b{-wsNeYo^!?<*lU1H`^^KOSV?n9yq8^O?RGX{03C- z)V0$pG{w~&ZV~9nr=>h@;=-UtuUi?*mw*q~+d3g*DP`7aQ{N|==l4Av*7vXD^AhRO zQ*Bw10yO=~u9o<##*S&AlHQN*lU?GZm93cPtbTdIAnQR61qA1w8;+-=2~j)uVBd?IYINzkB-bcb)hsa7t6DDqy0C_hfr|`VqB2ed z-zI`28CI}Av2VpshL&p#4dVTzxeSk&cz7wBcJ&3aiuhS)SYZ-tM{>F^ir2he6uNxU zwR7I@-(a*_5pumzZ7ybKCA^KgmH!aP|V)ba3__j+tl*uMKBV zJqh|vPXfEum%CYFbIg}jIj1K2=4>IzxT?iU8)Sh6M{6l>@V;05D~xwNxoM@gG+YFC z$hyR|O)2~cUG&MPOy|B3x%)mnVDuqKX2lymz^Py}!@0|vg*x_y=^mlozK@9Exa#&96mH9s*i?svYw;@nS5)H1emisid}m(F z4dY|I3Ln@;q6GKP zRDw~&(H`)w1WuN8b$4HhPb#sWqg#X^VXD88!tP^6h#{H1Sx;gCtL8mxjzwaAt}7k~ zSWIq}lESyfs20WOS*t6d$^4Sm-mw|8=xfSw$kL+{?Kw}qLo8btnPfBV6<4VJESW%* z_IhM%s6i+PhdoiN!!)#87XyTbx-RCdX?O@98uZhiNZU1 zA?b_F|4qEycX&I~sXuELO{fgXj~!-M+1A~b-h8+=l0}BD=!LT0yctqTM<%-Yn$LQ* zIVvT=^>vnYxmk+?5xSql!o24gckNnQ-$60ew9un;2R=ZVSb@bDeIl20?*3#&uduL zgQ{WpqO|W=Y`PX(RXBax%2&6aMX5wLBsA^`b06k$`wyhPQ@-t6uYRA5=eC)EpYz7i zxAd)5tI@y%>nvslS&^8qOv4WgAXz{NZkvAghh6dPs%=KQ_UBH*4v{4<7OmD>*e)}+ zk3Q-Zy}4{51^eT)NRbH*uOGhj6xy3YsdVHv_AXX(b#49Y0hj^-1TB_Zz?I1-CfD(; zK>fU{0}}o?sW&^#u9GL(VNm7k`Uhx|O80po%l*~<5s1$t z>)lvpwEqdaBW5Yn3&L}Hi`=)&*hf6YtiuVr>0K{J4Z;uy=mPJo`rWYB?658+_^W#9E(VP?2({u%HSZ(NEt*V)S_{Xv(GkGaS{b5!L+aQ^CCzzw`7 zH!ie10JZT^S&lML$W*RA#GsX89lp&3c!$%c&-53X_QL93` z*E(8oO_Gu;b)FT+%)fzQyJGb-85!+(SiP@E+IF2-U_8aEnXb1V6C&cZvNoK(rR3F& zs108&e%H;9E&Rhx=~180#xbiS(53rs1Wz*QLbu4CyacLSUwh|D1n#U`sH3cR*l;EF zefLQQojrAfT#HDP1;2E_emX)RDJ)Lxn?T<3z<85z&A0Am#|es9)vU}nO;&Rc-t^C; zt%KHN-6?Kier(3)7B)O&BU6Sf6@+)qL}+3EwRV?vb6^a-+eT^E=T`AWTuIdRPH!{$ zTnt`4EfbJmZ-a-pEI_|#uir**O#piaip#6LrT()=bXxV9(+(z;4U%HE72ScD}kv(rcH;W3wIs+S*g3Z?UX_) zoAHF2Oi6#ZWwydkEEZ42^488eu7UYv3(HURsl}$jz28#uldhfH&LN%8j=k&ld7UCk zj!d0L_0TKG$|dBQRE?ws?G6DpiY!coH=LCG7q_x)3^15B=agEP#4!c7*zaye!8P37 zz9v>Ov)t3FcE?ZUa6Y3-V}bRl4g*c(J58XYD`O@ z4m7@gLz8tkatPZ*%cwI6NCjg4&cdaHX-v8-U|3-YW!l-AO!wGBS_oYmZ8KfeBte++ zF(7lZKe#6FG1NwHHYU7$rbvOQp)p(oYbrK2&0VvIfjVLIpa=C{kI4-a$FC5c{{||F zYb%s9vmAynO}UsH1gB>WpZOf2x&AY8w~=qot_=ZmM4S_ku7HQ1OpS~yysY6zI(hC{$7$tuv~!*O_K29|{Zbx2wa<7dscmL+UE0R^Y?rQH0ynXy3uFg)!1>fSPQWni zF3-T;FQt-=%5|F)X?7W9y(HxfB?&2|K(&p)mDR|5E+CmI+%7*@vjsLs#nyslbJN>Z zSu=T_7RsmCfG_6r;j77lakGs`(bnOk-le=YvA>)9LyA^8sZwe9QMbe@~5ma!d{rl8HVRsUf8|x0VeMWS5yw`gfe&*(vBYq%3QVENP{5;DVZKAWvID zsT=}4E${;y$Ia>EbzhskUEoX^bSj{~TTYIsQOEF1Zzy4k8I43Jv5e%mWFA?2qu{DY zy0(ww1&v5`ByM-tPvpa1=uPD7fLO^*fWa%JR!n?mW&1an{DyNG^4lzDhD@n+#^5Ut zf>1E|S5`TSQBcd{g}{?p#~HV!{}Ai@f6)YtKyk{YZUzx zl_2_OM%y@dAwP?rax4EPrWtUUIfY{zm%emp<^H-W*GC6YT@B#J zKEQ5AF(<$cw+!pp%77rEn3I*;`l<49jmeD2olDqX(-S zZv5&csoZMpw0ZQ<2#FaRvF3`uw*+MjM$dIPO_S*lH-gq{SqK+HbeY*s6cc8 zu#?G13U~bY0@mSoms5ac3Ov1j>-?7|)TS_80IVY)8zry@Jg+aS3Di^DuVJ<~9l4dF zaWT+K$Q~8(j8~JOaL4m(+`kWK!r!VALS%O3Ciba6zGiE3Eu;Fl4q_ynMg?;# zqskqeRg_q3XCXsBHjfCQ6T@{Izssws{bG)`{c6_cx~dvHZ%#uY2bR==x-pN3RN3lB zeU^Nsv$p06x$=c6t}iE8%11NZHe>C$zOs=oe>^oVS9jWMPJ*3L)D^-PDWMby2c6@7 z4l>$J-e@gwf^GS zPTNG$#wkrn%*uwF^Z)jK>v(1*o}v1jg&65sYGK1=epVDY?{S^~wKZX(qw+LmcPXwr z)~GFzz?0<^wG%_i%7N=gXrKh9Ty-GBXyE36)c7R@1)Cx;8#;ze|FN;{6^o)BxQr*$ z{jM%K_(YvR@Q6kfDJvCjfZ3K<%qmqNxip=`+tq|D67+snTnGg{t~0;(60#kg_W`2OZ}MR}Xr$-=GeR$kUAoC!ofOBbHJm@{#Vh`9$+kixUY?tgdI(M zWsuwej27LowtMx1AC~-eVB=qmW2qKp>gBiXq4~9bwW{6PxdV;BQGq!O)CI-(s(^k-&+0)RTa0u7a zV4L;?&Cn+T7LVy2rfDQNd^S`|uA&8@^5J~AHBq2FKVPFk7Bd}m++p=we!yz#p?A*k zU$`x15qT$2dhZ%c?|-g{(b zhwyuUT=(~T|9-zeuKT(k_oL3|JznGadOn};qa%XTBZAO7=F(54#9unat;Ju7qkOer z9CCs3V)R3j%P%_wu(3)VrUU5LT7Bi&70?jrRCa8NK-Psu4}m4GVgZsx)Mqwh>6c3V zCtWJ&E1Xdo8!OqL^e=a*)I=SOkJZ0CcrIU~U6Nth`AbZiuGyNd+0-^HsRj4s!ga`z zW-gpnAxv(gLdv~*qT49(=6){&_#98Q!dbpWoY*EUVbJAyRU_HG+n{b!_gW3;JN3d!ggN~4iz?h zW&5L8Y2zQ4^)tnVdc~_&&9#lHiUx58?9FXtRgOIh@Ipnldg3pa?gwEPJXFX-^AdyP zKk#0gRN~l;F7Y)lId!lZKWc7m+ri^Sg6H@ZT;Xly&N$Py)su?|--FDpB_c=M-1mAX$R5o$X_7%eiu@!SXyh)Q95&*7AK|%HQrg83Srs z+QI5)L;`QhJ`~o&r^+sDC-iXh-C?k~^JL`q3VTjK2cDk0$nP^6QCuoc`#bB(%3xNk zd3jr!&02YL+aietlpPPR3OkoH<}YwGnX<5(shCJv%6~yFD4iIia;@f2NzAW9tou)X zdrU@coKwV*Yo{xJ1sj%@cv!-UU++)*|f(&dBzK0=KopR z3(9i7_Pvejy5Nu8_+<_ar%7+4kb(VB164s8szf*I^NrGc2e+`*opcsHrF|fDs1S9> zP!dtN=m-9KmO%7QtgKkN)t8x=!mxqzj4zhGSLN`xeeu?QfAE{#=ht#Cz}J#>wlnW- z8*h{ab57NcM!7E*`3515RcL{bW)hJ!>4@RC33~7bvMEGf%KhaS|1HzJ$K>MS2#pwy zo_b7K2#$0YunA;vDY)?CjeD%3ROEDIlBbKS_ z^TV$~A_f*Q^5=hD7z79LK@C*1=H9rmJ+s8PVwvUuUC(Fn9E{7ACd?8*n#=o~ELv0O zV}B^cOK|ANvZYfeLe?X$162zq?5EFNx<*ybf9Y><@pZu^YixWX&MGveexcHY7R!Vj zXmPn9ib9sr>!*X?5aNN%q(5S=5;(rjs@B*Xn9oI%;UtggGU(xO^8*Jmoy^Dikr~Pn zcu{?{k@@sJR-rZ~mPpgqlL}GHe|4sWvCWfO*2|QQbg)5wkgRg7W5N(;#P@V#qGF&< z)AZ{cfAB?ya{9RL>XYZi)s|T2**#X4OIglr5>)Wrp~#&ijtQpigc(U zY=GbF+fuB7=!o?K{lf68;D~CGBghQ=QrB*fujQ2`Mai=}Q0Y%{)1DZj5fmbykTaRZ zFl>PEZO7S54`vBoIYRI|gWz{czol07d&;%CXRfn~tskp=s#qN#{mCE9?KYb<_TJgK zqdorwJ=Pw}SP2KI2dQ)m*cnFU?{YS;DNzDCM1I=lEB<_q4?N$(paG1fnQ2ZzhoDWv zifoI!-1=Aeg!&l4-l9Kjim6`~<$pjrszhjx^5mst3Y@JiqFLh$X+C1=Imj56H2th# zXISL?d8DF?Q*(Dh!o7O5+X$Bs`{sOCAHc2_x(+tN-LfZSMNe1ec-}}N@)!L=LFga} z2ID>lU4r(%w|$fvwk$*MLs_%gYmrN{ROg$BNh=8^Glh3v?5~+?!k%hX@9F{ z{qt^3YR&l8IK63US8^Tk@GvpPw(t3UPbyhLl*Kq@y{aBksS|xE3l+s#>aaSm{O9Rrd4xXW!%O8{D2G%y?|pZj4|)FVxZ7eE?zBA95~>ZoM< zWz-99dLf_4>&IS4ds}3ppRfvEU8S@CloW`s=qR`8r;%;lsB(boNt`JK`2<@)Jnci6f0eM+}$$GI}#Y*`#SzaBZNuv;fUaIN_ zmUoY87wcGK1swJajN%Umd(VFplsB@bw~0qtf7ZKdQpLxLe26dvgX2;?NHda=;R~|0 zR33lvA(9taBq(H6=h*P_;P-Bp6!3@}hB;F|wPb49nv^!tdpd3x9f61H1 zyQ<-mgMw1QIx}zJYWVXHIKbQcRgSu4yLob~-dSb-R%mi`L4XIE4^f!p@mX4rtoSDQ zF=bnDuSv^+HxIC(3Q25lSTj;b9E;s}P`E+5F0`9D0?`(eTR<-;GG?yLmusR{TIIZ9XY_Jno z*NcBFh?AHlDEYiC>TnJm6ERZZicn>7f5S#(K>PKaFtOxMg#u21ylS;u8ztn%$I6>=cm4*9IqW<66 zm?@!m>qGkDB>7WW^}w)95pv6rl1;aa%p{S*zSv%0J(0n zsV)FE$Pl+b(Q7X2+1r!R2M`PSSgs7HF5pH=XT8|b3;_qPY{5=6|FR%-V!JK%O%hy) z)HehgWKDWso8tY3_kw0@`SSLeulqLRy*k|EO3vwowL zCB(xh1U`@G73CoKSk;Bjs?Q9Y6E?2U;re1tgsAO7Z`a`0mPDnn98-%n9}{>>UEu() zUOGJ-7hCup8=@!~kt^Mww9KprLLv!eD7jSiQE*pXkHJ9GOF%t{*^`po$jvDM^~PGt zB3V8cIa>PkB9HZMP=G@^zM862^kD7Luab*KAqxjR!GozSiHcP@-wvFJAo1wEz1=0{ z)jXH*!x~VU{e3NkcAAFy3@cWPacWbL{fp9BHaw`w0ii+C={E|Kc0~P|S5V#!>sEoe zU;$qDER*9|J#VtU{I;b|m|5myJlkSM=ay2ZtS&ohdJsQ<C zifbzpnyrCcz&9agXabZP!!8^D;Fax9LYW)9Rqnp)(#Fv|fyC}>sR(IAxj=$jbJjv% z1`VA1uhwaV3?xsUWgdWpF52p`kli?*79H6c6T41)T(y!4oo!j^Ay%hT_C@L;l4#0(j9>UB-1VeVPWddl7-}#-@6L)%5f1wE z%}bYdP)0RTKg9cjiJQ!C_2&g4-u=hrE+Im}IDjsM^6M>xS~}}36DSK8F-W)%gG;oQ zf`Xj58W8s2i-C2KH%P1~l4xAn0Mzh8A+@YYJHE)M&QYZoW_4{;=YNl`gbc1}t;dKw~hxr!T;P4#iw;<^NzBV<) zL%Psfs>KIsDDRb7=6@iu14>E5x-ewU{$26{LjY(W(u@~q0|7Mn9K$2b>Vki(VQ4>H z&>&+(7Qoxi46@hVuG<)<&_xb+AzeRbZ*uiJ3=Q2CBdr*z`rN_N2F;I zC`71c0`R=D8gGkxjUO4-UblevD*FemU(qW_ejLL;JzE?$@YZe7d0r%8=q(&WbSFZ+ zVvD;uBc|L6PDg}?b6L>y`T?oW0CQ?*f^WSQ{=OZdYPjL zB0i&gdAD?^D~LOSO5>Z)Uh0vl&S8-1oe&6wML#{XtXGylul_So#`^&bLz|gymQ1+Y z^cGW_rqC6g^2|2lEyytTYu7=H={}(|x2DB&?T41;=!~_j@~wz$@b|GZlv{MXKcHu$ z7PZo+$z~xyJ9tugqv5=jCcGb z$F}|fqg7PvcS{)FW$wmTG>R#|)=3_ahW*PI*YxD82{O#e{;r0bHjiiOA;PH0@^@Wy3S= zqh_1yIG8iZ=%EV=xuC1K<eblV8e{R5w9b-on@~6A`^MgQVyKL(!~SoxOw+0-z_z)8KK3PB)9p zI;*j56UXBmw)XLILNTnXipY(EVz|%}(O(F@?ZBKv@1v&vp{RgPd`+)NV1D3wNl@i! zC{h<-_ebC=8Zcb(cWX*Fs2`m|F;}VbF$$kw_*#kw#=-@fKJcIbB@Qmrc^DehC$kRv zi&Y8!e?x+4*w&3lce}Ek(Ht0z~c2m_$b^{;I!ZXpz<=^ zL5ubFrsiq9&wcR#=FBZ6!b~t~BG91PCgRd1nSH4SoW;3&DSpUn(WGqI|tR z3?B^bza_~;qfW9U!g*!xtKpKIW27=;$g_)7i1fTzB2~Ihd@{Wt6D<^IMcU{}brnmP z_W@q}43%=GjEC=$xDms@4X@a5^ozb=ud-aN!s3%v=41MMCg$&ac-s(X_q;4J3+OKB zs9txa(pOSuu9f!~x-m^;MYu;-M+2(Vztt)2rm&snClSjD$!wSD3?40ne#{b#ABjhX ziAR(O`LL+ToDNCxwNSMsge8;e9Fdh201<*zAaMa}lUwTZ=7sO%jck8>)2nul^0@Kh zC5s=f!IL;=N>QSrO8X!>yDf2C4W;bm_1}Dl3vIY-Hw7V5u1O^ZhJ7m<060`_`=z~O ziPWXUEJ3*;9z<=O8d?(2y$2!7OLbA)rG*?XN{j3|xY zzMV6b4!W%!FW9<2Byz%aI59od>UE3fA(0xz`+(Rt6!=nqrBrfdP@!!pHZzl)6zdR0 zAPQ#7TU7OQDa!qof+nO|keS3I>PH505;tZ0pVXtRr6!U$3hbiZSCEEJxU8q)*r^_0 z`#n69Kj5s{x>~QBh;yV8B1%}@xEFO$p@l1_5{BwG1+`9HJE1-$G$NfppGH<+KK({9 zINb|aIM*x5Klvt;r!#f$w2a=b6I}t33G)XS`IaW6A>w-gGwI+Li{y!9=_Q?)*<&Yy z80=(GVG7;MBI6K|1YaZ5t>SOkd#5y@qRC&c@FoXAX!IS^E?+3GFNBx(@b!dT$n;6A z|EEOL-y)y*IDWQql0Sy2Xl-VM;(XZN2jl}F{M9148*JC}CLiMSF4Ky7<&{sq1a#sF zl2uu^-^B^a5n@pQaZu!9kS~cfq~h$ZltQRIPmI5}cuuW+Ip2q8SXRn5V^McC=+D z31h6@rjg7m>VzEmF&-fH7L$mE)GH67eF=oa5raj3C1j&X9*Kte2-WJ9@h5&fNhjy;Ce{>_Kd+$s|sECrd;ccH@ zDrT-3#GKi=O1vWAg>C?x*uU|@BWx#U^__&eMcIVz?p#xd+=sq8bT{ab0Dy`I5~=Sf zd12WmZC{gLa!QZJS370qIxMq*HNfo~418YrpPCWQY@`}H7&`$|U);Qb-$HOt@NEBB zLw$2rll=9|N&cd^qB*NnFukbzCQns2o17g#FF)%MF$MD{lU2UdI`4CW+K%jY$Qupg>VM!~-4cRqyg3%K={L?VqXAroya$C( zseds@D^`G4!v-)6*q%opzATj{guR0vT#;xZEcIrx3>fq4L3g_dZxlF0 zHWQ5hfAxcxpfKy zIcsJhr}u{b8(06+1XV7QPp~*`;i!#PAxn-F9ma^uCMXh30JZO5UHzmP?63O=hUiQyR?UkC5FFPeM)3X4$5%7lln5AhDP&4M9{#BN1lf+AtGPp=D zYK#U90z$SwkEmlfknPVXw8b49b(Z}{w=89e{^&VN-dsApQ9%hWPFhq$O7ouAGZaZ} z5AjRk@ICL~^!2laRuG;pp8rpBp09U!HK1yKJCIB9;>YQ0=)kLdjTWcmVD1Iz5p)b? z<~kn5%I4_US>8u@-keLCPa}y`4FSRugqUct5_de&gM1lOnG3K7GGuQ}eRX!uz$I(}p|y4)(A7%rA|#HxK9zDqZyQcPc+h2LA$ z_+em9zTT@F>l5HVEvZl6?ul*(?B&%OHC2d1)}#6VUHZB|wYQcLn@ zh<$RV`_$RNcJshldJtIp;J-_cC2AZdeiFxvP6kZ#%W*>sTgpKLV|wPVc>92B@h0h_ z(1&-CXXeg7&s-qPM%KcYRX%Op>yM^TJEpSMvz_ItV`jos`eq4t z3Ap9-Kfj2@(+ifrJv^Sr-|YHfqWn+L)P(wdu2+V6VS#t`J&7um^sO|4QgUVVg|a1$ z_D0GJDkJ}r{kLE;WpaH1kfx8pX*qIwZi}(KhViiE8p9*?N%~XBlIDx^N^+ZxM1

i6z(n5>XT1iAk5=C}D_$QC(WgRcxnsm4UQDjzp%LK>m zAS_9ye)Jbe%Rv_UeWQU=Vt`FSrLTJwdC7D+ug-ntz_pT#)zT@sQsj87d~vqpp+4Ej zb|;5X7WL3as7x$Ii1=n5nfJ_-pgKX--|Fhj*ttE!ZYDb^(tZrw?J2)8S(+%%W9hzf z0C0FI;rO?}Ve`ea&@qN;`KEWGETnyaC0_#*i2(w?nB+trNWYcf8H*2!1wGBH2n@r) zL<4~81<)~r4bP!xO|h;-Q|w*x9A8{=8SQ zJo*Zbxm}l$jS#8;>f-;X4J^0%aB z*W@pA3m%zDfu$nA)1(8~ML82d5e;UPJisdO1tpqRYE^G7ywJwq&uUG3Yk7Z_OjB)< zRzUZLjhA8iCzAx{M_kGHP07T2ma#--DA|5z0=ip(3ch3RYyUi}8AyY_dMub_AQ26P zcSllXvw7_E6XcWfA1IA3L0o|7;*|v)*FAHJ&n+v%h)wRaQVRmQ#$hT?X3v|lgzOel zK>!}{FiCo0QKXvvCf`ME+Br*F9@%oH&^NY@hS!T`O3HdLgF#OM0Eg(^Pavc9fK)-%|&0FrK2%)g+&x?I? zG2t!|{VnO0XpIm71x4Ss2hNoynZ-sbCyaTq{`;UuxN4Zv)VNn*o;y%hai2pEuB6q5+Ni z*jfs3R6GuVL^Zf>A*}eYSlxS?MS_>=0__z}fjKq1M>fa7C2|Lx6GbWf zTgGuiWD|s5_w1Kh>cEAtSQr*vx|htE%sS{U!Ktx>)V4j&ZAwQQrXk#{* z{|tvl-h;j@DSUjdNERL?Q_XYF&>-h-T|olTs~z>-9Z`zFW~&ER#snq6RP6t`5sYKD z61CaP#gFDX=-~Sd&=Jj6BC6j&wQ~;8Q z0ommRXO8z^j7p__jn4m=TX9&WW6;8ts0R@@7U0{WR50ui_9SKDCF z%h-P89P*I-(xQ(AQz<+qv}g>+P~h`;w7&N6-QUw58h(}i(=mvbhI!I!XEezK@>fF3 z5@MIV?xT}=5nmPo(-k)GJJelresSULpvfcq=*`tb!<{9*sD%V=g>tt+4r0kVN}~b( zwoG}iy9|M+O4f|;sRi?CLN4)p_8_90|1;s|142}q;qVti;O8gYd^YvQ$GoY3T)`|<~$!E`{Q;N>pAgE$Od#MP;V+rlw#k2$-bD(Rw7c+jzj~V(UTxeNt*IzbN7GZ zDlH96wv8>y|2K&Mo1g#+77ZdfNi)|c7|+1B!(XO9Mmyiz$T$F*{IFJcY$(q^-Z-m43>gZqIafd%XJzD-G zzCG%ilPazuM`#jB@wq=O*8<(;N@AHzf4`~t25>CIoezs7n!8y64$Cx!{+X)khL_6h zqcn~DN1`AAx(zML^%Dn@V*g@&DG9h?Nx&p56W&V(L^axhVtq)}S^l(Q1hVg>53!^u zZ%yNRdq0y*`_-b;+u%Fbh?p3S5WuxytVMIwP&2O*C25D5ZQ}<*U`N!>WK9od0mII7n~zAH=Hf1 zhju^NX;INt=-K%9{^;i9C~$wc+Hk$m03!y3o^G6of?v$61FG)9J_@=JTnlpmyoP%M z3RqZJD?2!GT?jW(2xH{*+s`y^^ zD~JR)MkIRJgforyLGr`un_tX>)Gix}P3{)6T10My*O9n%PYlq&DKF4IljQB!D(JdP zy=L=%t@3vle1h`4pg9wk`acee*CUOGtWwG1AA^$wSV4Z*Ex(7=W+Qm1t+~Jr-<@om z*Go&=D%g!@wyk;Scq7gkd1nXQG}|ic<4$E&`M-gDAgl;uE+#lGX+T^Oh#oFd2%Mz$ zEqqLhYSCn@jJRxylHhRw<*|QQa!ZHeYR7wyMyZxlpv+43_#odv@-+DrRno3mB~jNV z-{rz}$q=qf{(xsC1XMrZJ%Mi9;(4?C2jAJTOvXv3&C<5x3ir>rj>FEl{1Lg>)&NPh z@DZ_S5#lzD^Yx*xjuCznXv-jO91a`sU~aJ`S`DpqZ@w1@TRXhFb)N(uO#c28wEZ(G zF-;$$34DMC!vl;>XWdv-uW6Eq(+1Q6mjoMZ(I|P7=S+=Tb*#}Dj5Z-XuR=8Y7?aTA1K1jA-0 z#f47`el!aMet!kgW8~Qu%OGM2zzFKoe;nH6Hv*cy*ZBU1h0RKj%EEg!#?Y;)AVopvKENQLHZmV9Mfw zM@15m>lgDFRuh06NG9nxj+&eIp?@3tmD*J!v9+-N{${o$l9qfz-KBa|rTkqY!)DMx zs$A5a+uu5s)tLcTVt`0nWWy87f++%!WzGz^|E#hh?qp@eW`ldFEf)di>X3U(*M7L( zEHfw(GW>2yVuq`{cN-dV*S>5is5B&Okw20d+Zxl2zh@hQcdO*1eDB|!EcS9-Ho6HA zcT)NQNnHs32WF$_zM_Bitk3_$z^9?$HuJK~eAsBai*@shxS2lCBQ$^yXOo*{^sz;5 zYBZ7N&ZeeROAHal_KSXCx8NM!=0_K6>r6XiHjKEQ*F)8K8Zdl=W~^>2RT{$#+X2!S z{ijcC61WyV#&d|7f%d9?m$sI<&5kh&zay8fumJh3BkZRSRFQk^IPMK=IEDL_Sq zGlMYIIpKDX z0&Q13JGq;MZGI+1Jv);= z#>!gf^Y-R)Wh16pK(&`Z+to$T$o2ym>xq{0;y7)6o!C+)l*pdgeN-kI_%jeah2bvq zo+fyUx~*-`#8dw{Ri3qJrz8CIvM9Hbj>~cC zQ*kUq;O8KtO}@q2$Qx~SgLH`EMVi8-%jUd~ImiDyLA3Zdvx(THF2}H49Xd|(P znQ-`J%bZKDt)0i?DE6+RWCu!C?9R1gAYfcLpQ_XVfI#KP=mkla8vEBa%4R)y)-}9w zO}m2oOl{|Dv#ahhyY0J&vNsaEAXC(8^Nv(HfV3~c6lAoPbi11=$02U8R?<;$I*FX| zBQ8+@v*EJEdAJ?R)dzYsD2XuSrMp#}dOf$lw6$(f_{Z7U-dStn;3Sk8IIbD5f|_;=|@Q)`isE_*k}pEyy9=H(s8I&uEAO0K&2ONXHTp#O!j zBCN|AbuX{1z6H$M04)hXEu%G%)_IaT>-<^oeK+hHrb{lje^QLU7gD|bh9)=d)~m(J zW-rU0%f(a@Abp0Bq{IHfc3h5o)tT+ut`m26x*p}gC)5X@5P;wJ0sQv7sjS&E%i;;4 zsb**ba~pfvS8I^e7VpBcM_ON>lng}$B~GbRxnuR2Ue@=J!t59se3n4JAWU;c)gq$* zcQsAX#0K;KPjpwz0WOO!e~mqbD+Zf2VfWwHg!?7ql+E zHRoKdEDY{A*n0OgHwNWJtO^54n8=1liGCJ|zH!3R*4)u?zp-GI%j6S3!_{h>UMbMI zBx{N7x*Y!A2?3Yac>E8s)z}L#SH<2e=a_`*Pa&JJ5X(LpgL#X{!Ndg&;II+j%`8C) zLw~0UaEG%i>u~ObF)CKI;%TD4ikEk_){|lvdv?si-m5Ror3_DVHI|!@dIeIo;D0;i zy^It74QF7->=SUTaV&}ZGvE5ct@{34^{uGOoS=7we;>R7I+qvzX+2eVvZVXX- zUgua=5``N%#l>!=KX zj}cUv_$QmGuI==`6HIO{yS>4SEu%bHT)?jYn+O0w18y+`XtQR3LD(u$bJOgaJTiA< zQNWZdE^}&zjBD^R=CpxqXete49IcKE0B&#~G@c;=- zJg^Q<`JNaE-K=Iaz^T^SE}}bVGG9m)2o;r@i`lqhHmmjwCpQ=6JtKeJ)%phhW~V%? z)AaC!02LGDm(i~t$lj*Rx*^DB`vYrxO1JR+DfgYMeYWDF>E$aCWj-9$O@i1K6e>vrsX?v2 zZ=rP4uklIlPl`JC$6B(Er!wHprow0$zOYv-JwQAF`T%H;VC3KTErHZ6ft5-wDQ
rFSJx~|otU%uZ*lS$MDkk5S)>;UipQY&cJ=SK`?vL*hY*`!sT#=BhF$gkt> z0m8@21=}Z1^lGQ#^P!1!$fXUZY*CG1CmfECn}L!;Xc8H6;G&i2-^W0AcoddD=SPn- zR zO`lVRL1)K!9GXWEvg=E-Sr}DY;kFw6z%e!Pg6!QWiI(j-I|RxWh`$H&gO`DP z&V+Fb?t?$!%QQ||U`BTV^l5mu9hK^dp~wX=7){B94Hng&@0)kpV=Zt?#yXD1lvT&e z1w*?|n4`H=+-Fjw_gKq+t6?yaJmnzd5&IwPrws0oOuX`zhEO|DMgE1>xxfJ{tqRky z8arEOv|I=KHEJ6=87!pH`tc0nJ*?rCxf-A?Vp{Msmz zJ2*eIBvd4%#omqD{wI6FlswpJ#c!VF0DSI0tycs1@ce4O1f?5*DN^`OX18_Bcgdko zD-E%F!)d$#F@W#I5~;;KK95%L#S9G63b7}Lt-f=Sk0BlFF!}*KrK@szobT~s+=H(j zkJ?dBOMQ@5ptrGrrUi5~oE$F)RMy;bNl5E9^AgRs?mAO)cl5kkeutmYM~@)MC}7zj zv_Jt%PA!-QJ1_8wuRVlkF(QWYu9wW%K9Xa6Q-M^AvA@#YH;5vCV4ncABg>o4-uhTk z)KIodmgvQ=BEv^}SwAW#OgcD}@7ZXDOA^=)PNP*dDSx_a& zsjuA(Zm`*aD}o(t!2IM1Fe4!fFdJ1ZZv<>(xs5td0tXZh8WD%p35vnxJ8YO=^_Or; zSvSjBK&60vE@(vbA^=3^fEoer{hP#~G4(#^yS1SGDmQ~R2~W=$Td79uP^RNx41I20F+jxR-F6_tGK0&Y0VU|ueM1We zz-~Atz*rLR50V$y=fB6?m7uPwUR$+kTXgqVa_wEhi9VVhyzpbLo#AP^k3JU71Z)-X zFM}k2Vu<8+P(br43IoaBIi0jxDC8WgHLMu)R|v3+GlQD~4kB}FfSf^7oxR4YTRG6U zJx+0vZvJRzLwYPB8*@)C}-W$HQ5ZhM^_n1nd<_d7C zSwDG`V(Fa6!t#GlD zBEkSkkr_BGD8HKq!<}Ypgf+2cJg16<``u|-%T9OTKa5=4T|%ZkE5*!iN6TvWG|icg z8l)EER1CwU!J87Zxun(SH)lIJfsSqh!Ve$=kly?=&wxOuxkGMpsHC8CVCd|e9c3S+ z;A+)CFAF`%S#rIbWTua0Xa`<>FpL3q7S{7#>?nmUq{xOu&eZ$1;}k{j4a8c0Oev}w zNmovu;-Banu>aZgMR%fZ+&1uCsxR}=UZ3I(c0W{AVT-D!KdLxdbeVqy9LPEluHalV z0p&o}i(R4g1#o%5^>*-2+QQq9BsY$J-<4QzlzD4@M{}Yw!tPkN1ZOC82NK#8F5Br6 zTCkm{II&z)KdiFktLbkh>CMulsdGCHSSyNZ;jHl6T}~qB@0vgV&LoS;37~Rdr~A1B z8x4>wvBnNxMa?}(XRdpD2G6)M3VLkU+r{w2@!u4mpoTwBdysYDv@g)M!#8!aw+W$7 zQ$cLi-~jDxH8ZwDr#p<_R5Jww{=CcA_ShI}o6JyoW&7=FO7~N>n2i$#_tF;LG4Q0~ zd7b2tspB@Uz$&?jTqOpiGDv@OHc#IEp(%)CX-`DaQe&P)8wa9`$Bq?q99+ceg9=VR zzjAdLBm->mImU$e7p-L}Q}5jEumHfyR)Idx|TD07pOSgzLnaE4Sq5)jIFjDn* zWk`FD+G$aCqbWJn@w*w?w_ug{+gS}qtAT&!S&s`_UpJ<_sNlVe6jI>qgn*8&|{2g#WZiEv$0zN>9!pn z{n9}WfMFRw$LiYnJ3!mJ`pehDFmSJ_O!X%0eAiies zCwKkG%&ETLOlSL#@Sk7x+i08?rJlgR4F{Xf?IyrRM|W#)pqLbm!g6oO@$WP>Z~J1!}ywPRohs#sl7Z(ii|KF%&aq z0Kmo?_k&3k{OzRap_hCu8X$YY0T)TT<=xX*F5)M z-;u{_%s&dgI`H=io_F2x-TajvK)o&I5rM}*z)xuo9wu>#zRR9@^kwLJne$dG$aL(3 zgVM5v&{gsO&jjZyn;B-|*E*m@TlKYPfcc>oHdPuRfVE^) z$!qgBV^cdjNj1`u)9tJ977AN%-8I@=-H#Lyjg=(Qkcu`sm$G91t^HtmJLWKKZc0jDEs|d313-&_h?0AVTv5qFKeIKQ9y3cD{@kb!cz@#3!zd#wXM9%-_bW_@{mZN*mm8f&2rH z9<@MMI}g;0mNaOy@U@~Lo$ck6kQL@VrZ>=GyKY-rtYt>lW#RaF6JfOjuB#gYss{`hVNX3AJxN5`bU`|A3WdiH^vhhoRqTD@ z-&0>*F9L3VfYhcOV*f6Lvjv5LZTMQ&1i;Ur{_CLTOxykJcnbT9wmMvlU( z?ydQfj6w0XYdQ3xE$qE&MR6(kV51Pn8`l;5Kj#4n!iE6s8Zg#Hf+U2Ej|DtBQDIfG zZEoz7tdi6;8Qrz5bJ4WHVV88Z9}ug0qU_FV0=OTTW>vG5c;rCHPs3}jZlkrIRWkWw z^61Z22oydSA|~o=nR-h|b$%sNx=TQI-k-HF<<2$Rvt`+zTRI9WHi8@=aiEv1K!+xdQ}=0$w*qHZpXH_D6`3F z&SKPu93k~Z8j&GGeL4Ab&`F!~!80~J0QmiYF_Q52ddU>$@p_4_O>8yt8Xf-w0q2ZP zr|s5Vr_EPt{_lFPjHRzt5H<&aO2~lks zTOlrPcS5p`qQ`6cPmVg$-tND%Q^b^&+uX65%Q=Ak(?gZ!i99r-M60%VESQ z|0XMY5p|+lWWvn5N$2D%2}LP)#)T8P<37Ex8F*Dx|FZ=S{CK?lgS7&|b21!uzf!#S zXEvjR1~K`crB!1?5^XChtADK8bhjO}EDOl4a>u*>Zq*hG)9K!QCK0Iz+A1h;`Jv}B zmQpGiy;a|@nR=sck%MrPXpW4(Wa;h0zIM-Ja}1?_|hIK|Jp#i#l_g-}1ig1aCP*z3z(#!e|R50eGeW z!wt~Lh^%%SC=~CwmTgw<1n&C5sY&a07=2x_RE#6F9J`IXEpzLU=x;sxZ&gn+kIV~uWo#BA z)Y>GTmko#g{v{dq{e!>*j_n_EqskvIQC%N#ee2GTbUQY~VP)<^iLRBE<=dH$3>TQT zd)F9$a&P=W{b{VTnI^sREQH+k&UZ7U6Y)zk3JciM4nNKUw)Y|+1Cn3*P0BYOI^I9s z&Q;T&aHQq(Gc`t!pNTIiGGjq|ux+6K_?n9cMKmye!XO_*o+F zz#=INL_i^H9Ryw^*>kw%EmJ?T+e@-px(bxUjq$bPU)A}u_3SK3KtspFRJ0dxJiZzQ zv_`rQS$~?M=%Lj9hzVoaQiAJl*wF*I0dHy@wu#bAMOoh@naumkVp>&&WPJ6x!-x?Etn2aB)Z=KvU z3ZXp+9jT7tARas~zw!W_=e}Szqeu#1CWvrY&hwz{JNvUFHk2VM;<_Kso?R+&KO(@6 zhQDlO6x%mf6=(N~N+EmHUhQdG`1}|4ui9HZ_JY@(V_y#^zVd|-6TH)xFR>;#C9CdXtQ&9IhwqzVEXx)O z2mEjGqT*k?I2gwH^S0G_(LlZo_m6(wjek>bssa;D(vypSANX2iS`z|l-~|vklZc*- zOI1V?DbZmpg42O>KIkV}CP8EFUYX;F>)uVf=jBkJc5vwe5oUUQ_ePQuAz-KPTOySZ zCyRva_RBEhtYv)n>-)S;*=EgI^?v_SxQaqp;>ntchCK6w2$eg{uAemW(R%lv1|K{s z`qF0%mz{vh&WD*|YX#s~05k$NGjeHu_z^HL0p;PR02sJ>%+kRlE~>tN(b;P6%EE|r z!hl+D-tfYRw&4dR-0agkcQwuPytUj97amQ$+cCw`c*e30?^P*^q|)D=StK5pdOuf% z&HjdCe|8W0J<{C%E5fI}Dsz&3bC->GL{hV$A^Pt8v?f_3L*o7uiEt}v)wvckPc&%k zy?{^wECif?{QB*;+NGo2_D6sc?zk|YWEz2Bmg1~bGVHk>Rx%a&V|V4QP3?uB9E6(3 z4!(T?a0a9dvV1y--tz@m+@l#O)fqOh$iY%~om^TsVa=N4Mfj^Zw#?IvCAIB88Qtww zZkrK#1^*1FJ=o*_9rnQ}^{eW$k8()pGD4>BVu)A*!{&g&P;1a`dw!Q7Kn$D@V{8@H zt=eE}@5zcqBql_Y5x6+gvHqd|(0ilx{eZkIH)8-ID}Mzz{SrC%z6lo}8Ej9#X!J}g z!np0OY|o8Br~-)F^~M)AGK>`C_h5=+b&2pknq=mUynRuz(hQt zZd8gfV3k;#rKO_1CU#unS84*+&rDM>cjs=d)B|i4?z*%WJ9woC@FYBA!RibEQL{g8 zvy^~m$3;VhC89Ma>u(phpu<4bKBmNXkA6~lc8h$azx&B?@@dKSxKTd;5QRe%puRv^W567sLV~C z?MMQF2lfhZ)JYz4?xmb1L?SM`PY4{rI{G4UtydWRv~2uaYTqMsDwFB&{v1)+r4H9I zF6@6XIx`PuY&*dfi~N~6U|9}B4CMjqVatFmNj+){QU~vdg%{j7PL?yvYCbNhIq7U@ zY;Ycyjx`^x#V##>4T&t$(P1Z6gd3A5uj+3!u;;@qC!fZOf-m(9fOb@ft-$jOWFost z0=})txTDHnbzd}z+_hf2_DHcX!PPmBx@1auS$wV{Ni zR*4&Yz|0tYQ_R?cPPyPTg!)jO0W*Urv;8Tw7s1n2&WLCC6}Iu~I9*?(xJcQp@|)j2 zlIRt9a}L`N9$R?UobKh=)Dg2jLGYUf$axK_8<1KEc=ygNw1#p!a^Jsb!f*R=VADNH zXJ~9&$d2XwGy=@?w}$%7G@|b1hLV(K={*ZW+TU;M(HbN1eA-Rr*Z zwYE$cFz;G2b)0~YF1h-vF?m^WLa7J0<$2~TAG_-|@sHDitb_w>IX?(GSugMuoW%i)}UVL}<vwR3$R0$HrhtOi}-GZY9y8 zEHf^rf>t}oOqJTt&`guMz&E;?e&mo$_LIEc=!71&F>gk?NaxMk}v`HF1!#^SP2^c_Z6No zn|sjE<@oa1DI^>!5>bElN~GIg2A5u?FrWbv(=33o zve`HO{wIaIf#9Z-c3Y)sL;NC*ubIn+XDP|5kea{ZN%T5zW8guh@MYC8@`2)YZm8K%b8}_y$i-X7U$fgZYDk7`#7)spK)CL|y)VA_f7cE)M7Cf1o)F%#QVQHc zHi7(shLNn(e>%mLnT_^Xt1Yn%)|Zuss4ivagpjoMW)TnVe-)rwU;Rm0-ah&|c`{(P zYi=$#O(7g`50WQK>GK2Hkmg{AgFF0Be#;S*vMsQ)vqN8&zr*$>HwTCs4xjy!y(ec~A@DMweXHF1rvU~eD?MB&*txs(q6= z>5)r-4S>+FsFfKU3!Jo&TN&|xHfGmPM?k;+;Nt*zBrUnXnYrU+i*Np6?{7AWF3R#y zhl0AG3-WKuxIT=lyS(OZ?VLt~c1U&cSRB@-HbFdemUQkiFg@s>$2VOOih+e}6niXZ zMTrmr?w}@ZGArfKXPl)1kQhIpD=L=H!ay5N$qH~G!l$`{N3W6PP)<{SG&Iu*kS!UN zp`IoL#99r9N8^jQFe#7KA$5E*#zZyph@5nSC`w| z#|?1j0CK!q@p zzbPja73d#pW#q3`OKM>;t6J9&+%)@tgAoMa$urt)QxC=dw-BHi@|p}u_jl!?Xjz?q z1V8K^F3m@L>~sfhJ>rH8TR{GSub1`Dfkhb1lLK0p?|gj8_8$f(j05>a28PAsesf%n zNg)PWsex+)fTlJ)Fm|@f9CO-IFfGOHPB)?mNV`(ms|X4+vI%SF zCeWE&T(|SoZD#;*H94~T*kAWGzPgQuXL}sS!q~yzHupF#glT|2yXf?RQ;{}*nGJH# zVC+T(dU=U^p6$IE^hvlPG5B^G52{PxdkjD)@b0}%zI!kmEv=y;waiht(vtbmgzZ=6 zBaKtUJJ{l?R>;0b^-~&oD@hh|(^jIK!^MyPcMZ9k)SvO1>;l{4i=Q-p{5Ch7^iqj{ z7CHr8p0{t0kjtMvGv2qPJ;|0o&(#Cc4H9;`vJ(nZqRqfu)IjiKaLP3l>*XViVp?Os zP$bZPzQolOMTkIJmP;CJy%_|~a~)oT-Rq!Lsx^j1fPmS@!p-h0+urK1fTXXZ*~Z99 znPlp6vsiT{cuG^x>c^-NPuCp~_tA_i=MHoK3$<1Rpn`#4lTif zgN)>Swk$?K^Ff&|i;Fd4`!@}yTY9sAKU)@VjKY1&fEtq`40R1|&W0yiYT%Tr{eNFG zS-~Xv?jBfYLZ&yq{Dco%9A#9&o*2Jg9Bj!y5u=zsA8<)zr|pBQKU+l z&>yNAqBrn6HzvGjR`fx=JgTm>^rWSspoS87V#^(g?)Ysua&OBs8ZaO)bNq9LlkE((H1~Cl{apfG^A;EH{4vR~G zcC!Dv>3~ZA{eft+xESc#eJ)YZRqs|E)jRg8v9NHo;Kv{OcFsrj{)a;#XbCp%aMs*T z`-Ztwvp4Yjei(ShPhTffHUEoP-T9;^6u(?T*1vbRTod|pqM#Bs=u2jK4nA?4q1~5w z6O^&F0EBuiH}_EiL?*nj2!f@Za@hW~GJa=kT{cX^RmOuU`wn=%PycPVmQljf958A_ zd7P%Q<$>sooKq`!VFk0Un(Bw=&sCT>y{7^z59V4f$3UzH`Pn7b&^AfQA6>D)Zc5ne z?|Hx33?!G|4kWvkYNUec?0Q<*7%?vWNuAERz z@z-GBe_4~;W*Hu_)=(=hCAWW3w!_@B8V)cxFbu!1Yn`!pAHhOC<}3DVJx2b*;9@uR za-iPuYN`488MG*`xnON(@#aQZtAkTe8sl-OEq*y!IM_jeZK55;`XKOP#Sp9{G@qX&_Z3^)olSBo1HOua^wHh}czJTEeA z;@zUUbHFp}7+FQ-m?32{VgbJ9+iwY& z@0D~4gI~!#wA0&kW#3%gIY|S&SPex18Al$^XaK4NnHMX6P&mq`tjwtSg`e^%{G zq5oDrN6EUii+jL9x?|bD%M*T{8|l3Hq=R+uNJ=P>QQ3j;vkkw z1M3vuvUDpj(x-58*3kMqwV=VajrbWM3-KzSPryLV^OAlI>Gpn2`9j%aiVDD^yl`ud z@2@b)Blf1`X-3zW6ks&Kui(~%uc$6A!b|DThkoS_Pbu`-@wmIH(&5L1fK~qWc8k@* ze%3`M?*Zl3?8#Kq`qonWg-b{j?<)PRN~^VPyVO8Ec@`!%z@%kVlwh3}ho<&{EC2%{ zl1`u3XxO30h$)TjSDxlKH6-Ayg#$S0dNhp}D|>kRFG6h6#O+D7^;BT_Q^Wb{#kj36 zr=>k*cZ3$v%TM$Gt5b3?id(eZZ2is4A^*C2`;UraTS4k$helj#*W-E%_s{eUEN@8e z4`?G-J-$@TvecXzq1gC}h!uKQmu5b-C=4&dmp*Q zHo5(l>N^tJj~hbT-iVG1qM_4E8Rjr^r{{D2VdgErXyuRFHLcq|vW|AxEhO0`jJecy zg`>tOHkf~LK7z*8a|j!U=VNN%^EkMUFVK)^#_Z_B+ zPV2&Q#i@Cvpgs234bakNrG23JW9?Gl5$(7AcZ~<2{En+XoRm)5`$k>bBUgKNzRBI8 z3FS3PXRE`tP^BQAf3879JQFZQ@8HOQV5?|KCP;gL&E^pb=C<-z1%q<$Oe-8kpix_< zXX};a@mE`YB_}biQyLFOI-W0rdS<0~3!kZV@Z$lnfyp$h|$Fr|MFX*S>krZm}}IOqzKnoDGa z>KEvRWr4hr=&!>904`*8K{=aOQN%1D?P#Q4_z^(6!DRW!eWB7D>UiS9{9T+HALn zjIH)XhG>8`DqAKN&XZhZs^m4HJJ)zQ_;7J!6#L0G1ZKjvmjP3Pn}FqXHKGB)Y(>aX zM{0L~J;t7We$WOLkD+y~EhH;xz#q;f*>O;j9?kh|W+gkO&r)4f z+unF_Ss-w%JMuLiL*kOy81 zXBOH&S~XV+I+W(;a*f^yj5b3&Ec|R2#b43OG(uW_bDE=&O5<^yIV}XVD@Jd0TU+dC zjzT7zFyiauVzY6=hiER}M>Gd+Dl1wcjmuhl^k&&YAj;;p^rkIm%DigG{qU)E$W(vh zpCd2$vq4OHazLRg?|6N>n}T@zcwwaU=~Tn=r#S!3E{VSAZuOy5FMooUU>or@2XK3j zr+tv>6xH^dAD+5^h8*zOr8o$d-QIxB03u?1?K_ypD$Z%c1b-fh=fw|tV0AU6PweUB zF?^$rDJ%{jMbe+Er}*)ZP8q+7S4$*{5K=Eb>rMxdNbI zpgSszv1E!Kt65((EM0nSUm&r|cE&k*M^ndKR1dj=( z?8Vj}jH>3p73_X;)Nod!c9r0^WP9Y6^Hv{cws_ra0I2Uj_e^ehPdV6Kt?K;z)huv- zPmwoUE_DT9Ja6##ZFA`}FfVK1&cMsi-|(Ie$t+(#PwiaRbcChSYzroryEo`4R$Z1s z2jPer!>T0A>x&ETSosSf|4Ju7xR>TvciQJ>mbEzWcS~ym2-g-uG@NkNA2HucVPsEU$`kpGu|I`)V++l zNR>kLyTd3~^mZ(!#D-1St@iP*lp5`K8w;?I(Yj3r`8&gHEVV6OL5JI|<$teVthO!s zm|oCfND%f|kB_BRqK~xk}XL-T9nw^oG4brmGNxNg8B}=9oqwo7Z zL&vBV&mokRr|T#)c%eX_wI6$5w!e6n{cU~~gfz=HCJ_JYSk80kMED0mg0iZ% zk<=s?Y{2-~y}odLoM{xV&g}ERm~L-_U)bV7-ftS3Y{|V=J^&b*^O@w$q(A?Hn2`Te zXtEG|%~>@FKJTlh=n9o7{eN>z*&igQuf#qKwg$!^=(Ab+Sb4s9eF(gcpyw^ z7~e-1b{b-Ad}boJLryCfgkp*+wF)~rdgO}>N%nl)+|Zv_jS_EQ9B9X8=S31Pq@D`Z zUrJT|Ik;l_XIYE9TdUz24Ocf}lmNWedi6%l9*G64SF|d$^C5x5U-&pleIDz-dVgQ%-?HxUiBH01o7xQQ+EqVisr(z0 zU1W@1E!K=VO|UV#@I-uBzYo>iep5@}8bRSr<@Uc{o7NM)yr`t+2NAM{xb)YpQTr6o zj%b*&aIJ>~R11>0_p|sSeW(6x2ZNJr9S3FBY}^A8!gYZyq{{_*En&;-bO>2t0$MsF zZ+c~UmgSs~cVw`#oBgB3R_|c)L-XvWkxgp4DoZnE^2|_;##j^V=3&Pm>v#m>gNp}m zqp~k>Ie4lZUn_Jho%CCMlBpGI=;rbj0d!Lg0ZYJF-Ca=EzUr`CM`}E6k#LISlp_?p z!8MCM!8SRNh-az_sE4Cf$)0hj@is;md(eHwhykqbWD4uIaWO?7w1Qp20II)|q^v){ z!~ua3%o%#~Rlv(Ik29L&$pHgUvW}?Fu$jNJv-%7+oF$>Qg{t=RYwTJ}wYC;D%km`t zPfVdliGl0yy-wyJ<=w7qCJpwwt!u-&+5IYR$xS652j&FcH%84-Y#zg*rSaaqzmudu zI4LBz#7G-7l>^69s!M&jj_7rip)EwW?tsQ&+L-m_pY`~L!0DOMS28KkcqS~#ERz;% zcp&mm;c#Y^S>Dz~p&8ZhTKexrl*fDbVbgM~Xou`!hC=tSS^fvTuOb&x%F89;uo!?Z zf;}ZQY3x=&-B1R5f7S6WXA6eE?#EuA+x^NNCriMj#XZer+jWyw!J}YHNDVwl((C%^ zCwXx~TWS^mdiIaM+q3WY0ti_HB!BSPMoS_KZ0VsX99yEalu3*tEX<4&*$2nKh(-fF zb3O0%F1gfWWg$G>Uw;^0@qz6~XNP`nTn?O-TDtL;KYmm9&w3LqFTNqj$eUUPD5-by zkEEJ+_{x`@c%pv(FNjA6q}Kb@oK)`+UWak2j^X`;oiM+@N^C$E_d9wh{j`rRh)DtR z#NJAi0JSMm&DlfnYJd(ZV>Y1&$oMDo1k$OHv(k+>kh5TCwr29%L!U~+!#IP0XWGX@DU!Ek`4S$ zI>G%uo*kaZ6m!2^1wy|uXy@Gqo%l8Xy7;G@BY5}=h7EIZs%1O`mXbX(yY}&<{&l*f z<_E8L|LIM+4)@6(3fJYOUqKQ0SLZML5lt~0uG$Pon(}#-|C@KCe=BQx;4`voLte$l zG(Ri^Dbp;dH7KFj)-s6g;61ru2Y@o9qh*AT@k+m})@*Q!?EFjFgAo$O*+Tm*w@&Zr zrZ;|d8%*oYDeB@QisJl&>m02<`Gbybof5XsWw`>keiAt8M!N$GmvRhq;UI_Yz`mYG zJ%jww*9u_+xAwhhHhC*DaVgTDLT1tXZkKl9_QPk(FuF3`_nIEBK=Pq2 z@&>y;HWOuLl)r#2aB%7S*jiUJ8Cm4b2~+HP`y5Xre}2zMqtugr=C8_eFEV8v>RkL) zqV~bO6=4eZU2!mtL}bA1mS#K{0Vs9*zS`8aEcT3~IiZ(d0k9o$-_Z(FU1rd^XRagd zZ;2#cTaEN8+i0GvU%IquTlr@a72-g~ijE!CF9IzR&RT z`x`yvwC%1gX*%0sLnx;wBck#Apg)gs{36DfP`E|6bUf&EeFu)T5p5dPluHWPd}&yW z%0(u=4$1wLsMYR3Xj}3^nb)?WgTcT)cInP;t(^ zpMRS9O(9Y$>)&1Q{}eQ4L`GdOs=-X7%t&B!ecc_B%;Wy zJ-3Q#bO#!CeGLl+rKxg_NgDBCr>7K{uA#Auc)&|Y1tXog#R|K_)3PCDGEw=;yl@9= zRs~Stl<2;xNU+$DfkMSpkbmLlaFHasTfkru{6vU{zM=D}?k9`~Y6Vy=`}2G&&`{9G z>+NS7wx51;C1+TnKXiVYS5uT9=1}M!@5&K_?AOg(_iNU&F{ql`SS{14jJ9PTaQ?bn zG5ly#MPUc_`Ky89z}{g40HMwPd$Bh=Vy`>mi-6^*g<;76J;n zch=35vJzSrE17(HW|Fd{;jzK^uVC1Bf<*M(My5g48_q#M=yq5b-p<2S!*wvFqfpr8 z-`~qsVA(!wFC;IwYh%CjW;>HH7yOVQ2y!u^sT(Bc#5gGB7R2n&)BOd68cXXypq5m zn>AEyC1460&Lm7;Z659}j_Usbc0^>0bt#Q`ff6x2Ov;N-xLuX!^@?GBer(GktaBKusYDY=q1={a$qfqx?mH!&|Th~Vh z{a_c*2JQ1MdkyN2w!NP131|Ks^loL+R2r>3?Q!G$J!<^f!x)ZFTo;}cUkR3lH9(>+ z!rV3W>i@lb1op;niZjlCvHMYxu*jL@L4$c@rCqr#FXt!u5{+VKv(?HC zVkYUs?tp}aevBi1AHKpMt{JMFM`yT+oQtbs!VQG z42{}b_Nyy_f+Nc9yLX32%*3(J6vw#Y>trI)=9TvDNAmFwPhj982 z`pN(kt=1sLoMOIA;y`e_Y)8{RM!$q%sCfmK>?)-RxUCjaq`&-r!+J5O*H4yBDR=sw z9KM{?tq|_0^5n=fz^me-em!lfj0}oeam$3QuFiOnffR7EWR?N?D5$TV;1?07W|A;U z&(rewd)y&?5T?TrYE{LEaSlV&FD^^lib&`XVh`Rh$``c)*&$oL!O_iEo1|Y)IMBwh zduXB<(M*wOIBfiPwv)lOK*BONGf^73?MhaL3w4YRmRsS*gbAacY%d@UZ4(7=eJ0bq zmRFv~QQ+$Ujxd+BpHKMgbS7%l9{V*|v0L6eYQa)7hSjp0T6`fD3c^(?%{O`N^J)KA z&RWRXr1V5#onC(QUHqaSbkd*dsEdyAxSp1WWhg>1h$7O%gk=Da$1o%x> zgH7wDHU&4xXdPGwuC|Pnw>X4^vuO0V+3tMbvRAXL`9O6%AHfElK%;GTVy0D!_V-QE z-GFt`PBy>Lno|tK6Rh!4m+up($r1m&2yFaM!;DIo`mLKeFm9aw*Z(&&+4lv9sw01*Eu*rg}hb#*%BqHvE=`pxxgKzG;$%@l_ za;ZoXM=M+Q&z($WMK`bc6}H`%A8su5E{p9NsbK^up&F!wom{gxIyR}yw! z5&uXOoNS>NSbxX#vWC7XiLX&cK$LXawumXE+xK{0)Q4!ATz(+huXE?a1{VvLu*Jt; zd%dBxgwEMf{m0-Vm0;D(CN1!a{<02eR*Y-$(BJgT=ITrvxlaux1y_Nx?1xn=mqHHu zqfVHtr$ECb{|NxE`~Yt0CwcM)mk$}KR!n#q7k*v@yt=BH=Hny3D4_eJmf9|pL0PU> zV^^E9;mSSSZ2e<7Yx$!)yNHb>RrRJ^SKnpioT;2_tYK>u`~ zoUWA`sS_1fYE3V8>Ld@lE@%+Ji@H{^aBsHg8?83m?GhLMdeY4au%_ zM5r+x(c1vx*g6j`O!{xe1K{@{f8mF!BduAHBcXV0r9Ti_hwEuvsIh*h`>Uw&(PENU z_4^4XjNLo&3iYWXyGp~K$7%?ZcFjxqDH<4E-eDCh&ks}uMEb~WG^`L8^o@Qn5x;ZK z^>@q1X>IfVD@)CRqmQ9uBA5Dpw^C)|dPO~Sy46Bn*};EZpx1l6aw^C;|77kQ zoiuwa_lIBgnfry4vYZB-^~<4Pl&;=ip&kXgVj73(gmik{)#vsl8(J z2u9BuamAs*c^*@0kW1=7Ec@ zvNOwHFjSfvFNNi@mgNmPmJAz^ZvfHYn41@M~T&{wXfK9Wpcky|&Ep{nldV zcsE2cf;tz0iC&g(%yawK`*MHZW(}FGm)^)B&3?X7#V$K3z5OX1Mx}VrXfWq-o;+Yx zN3$aQfF|1=M{d8RvWL4c1dKOWHue)73DT+`-D*SG{q2M zQkI9sL_G0*Svlc#YwBggb2H!hI}^Os(4+iMNBh)Z&?nIo1Gm}p|B%VuI!x34ZxcHc z+CPd!Qw8LbYWeN^^^BXQPW%9tV50>3T9z3%)r-zXm(n;qyv=N$R2!fq!9JG&h$NCM zY2{yG8>xgnyUpHP;tt6=UvV7!6S;D>+k<+JUB8n2_1jeTH=akj!IgPXB$jKJfXU;d z-uzMVMl_CYGg8-3N;Ox~4XFi$E8RDk!scXss5HIqez~4*SF@T?XU?D?H~M4PE9x~d zB=gD7CI@sZd;b^#S~2OM z+benW(N(GTkx8$89i02O%D>~j@i$#%=QIhx_;THAOeHAeSA*X|NhRjKdi!~m&ccy^ zCCX3;A-RK(_B_JwSblL*SdI03LfXobPk&P>#^#pUT3SM=F`*0S&}fg)>FVpe9RJkc7lQ_B{aXya(@R7bdSHCfr2X)u`?Z;ik!+-2>a-a?^!bSfjz-bMq zUwXGDF@sx(Cb6TPchwpOWJ|R7X(z6eMhXj#QI*OKzO_o$B@L}h(>u5&IaWnt2qHtR zwvxifk(9{hkzsVGDgGmrRWUB9j7KcBvBwPL!42gXuhLi5i~6VnPwTt0lVPK>uk!lX z0+*~v4@Pcq6WMYSl0uiZj4xK_mB~r? zQ8N?Xbf+}3O@$w*qh-Bz#vVvTi`)R8l((jp6X;w&HJqWcuPq%?)Jfxp*?F(J#~rfi zX!UG;s-HLS3tQdx53`xh_{OHq=N9IfsrBTV5V39F3*|!Lz0E24YF$fQu4)PlJM1G@ zvaz^u+UWjehym|U@s}`yjNzS$J85cF85XX=jQc^8l3V23lb$I1QHP&8wX+#{Z+e$L z+}yX&VDjh@>FPZkKOmcK%g&3Vov?jQg~YpntfH z#pb8_0i%IaNvh~Ie$<rg9C%hA=F#6|fzEyavq3}2xOoK$qc@2_F0Ml)Q!BR(cxbWQML8?egQ$V8SW*G@1YT?L(TBhe|Z0fEOjVpBmAQeX-7Ea+i zq&JG57ZSAcRo^hD^V?tHgz)f5+5+p9Bv*3MR|pL8v3}Lbl&xPdP0V}KKZDEj)Voqe z{Lcae8H65jHAnc|h)zbmVZUBu$l*<4y&v75ggY?P>Y(SU+&;~F(}Smx&bC)s2v9i0 zxsG>nwZ!Pt5tZ<4l$oCcU{k1~Hm3D>B?aje!FIB>>X=Q3V&vjPf@?X%Ft4xTW#|{1 zT{8qH=sNB2fH)}a=VDdjdigN`dZS1zX;=>z&rYYJ&VamD_En+3y;GZ0(;0Xa+;AnlFAyQi9hq$%I%+chm~Dc#zH(iLw^6LvPT4>B7CB#1 zpKvbjQ@>%|8Jnq&B^Dg%NopbAb~Pu{KHD!gDr54qm!qpDgXYFwA}1drPS?w^@Gm4_ zYlf1`-#*@s;g-J|RxijD$xqzR?&b@T?=nabr#*m+Hs|FR@qqO)-gE-v9Z;rTfMHj7 z?B;%BfwMb!H3-!D!rRKsol!EsQ(goMCf(qUr`rYzepk^wAemgOtJ$ye@75;049)r+ zRrJzUnD{8!!Ano>z?(<=h)*HO7D|VE-e@x1W^Hcg&PLLNEV;H=yPZI{5XVHQv`)bm z60N@v{#hf{%PNIv53G+$>6-Ub{5Puoa!zE|otbe}d=UX84kX~D7s6q(iW^sSs5caU zz0_jGf~W9SoaugSWAKz*evN@S?nT%Qg3E)#i%u3i*4yx_+?#3Sf9ZX`eM^ImecqPbZtL zJ#I#;`**ZK}1@ct}5_utIsYD zvsA<_^Cq*JY>wEa@`Kj2HwWUHjkTKz`z@)a#b(PDWecDC5+LB|VS`SSsW}b344LTV z@5#dIrr(0Qm6@)90giN8p6_7NUlh}{ATQv0MiH8?>PFIznCaUSjUYa&%s9)ZYx+oiYZ1AWJLY#0Mq>u1~p z`mOY=L5M#-3KvJMdv8a?L*6gq>#8#{wS_u-qjR$zFpqfv@74jk#b_S%7J3WVes#o( zk!E9P9bGJ|=M#`%w^sV`-ei4ZaO*QTf7Kk>Z5)^7)70MMD@FGhrwYKc5GnuREA5P9 zB)9Eo6*d9d|IWC356IzllTY8I?t+pJ;>DF-fS%kEE)K7sEEqQaBwJMTG=W?pStP!! zxKNXF5`yG>?Em6_Uv@9i{Yllxl&ua%O6pm<*l-CD!u7)~r!ZCCYoNuN8%Q`rU;P9b zJHI37*5c@4Ho1=X5d01z2oZ0WmC1X6w*~su+&=0JGN-CNP}V>*^G^?yL@qKu*Fa*p zYaR{)FUG-Ola7Vlw#^u_b0%8sC#AjX$7nW6B6lb_9?<)6d8>4`48ZPwwwAC=yKnZi zv@y#m9Zbfr3U$TTSiuIFkyxY9@R|9QT>>g6#5ZkSyf;*-^lw-P_$&TB%3rXkH%U-f zN|*=Od>GsN+-Q&++FUdlOns=U8;0vQX;JLwz%zTL+X#VlXSs-GCl2#(Mc?Xt;tpu= z4;9$-m_FI(=W4?+#M?XCp{sw1l3vNJBhX&WV2$S9u`71V8Ap9`^}D+|kRFq;UD}-o zEN9D4z(G=d{^Eax+eeAtY-zfK&n$|6FuSiL%R>q|puwiJ;&ZsFW5d~wYVKU!Bpbzx z&bGmO*q)?%;{!KLN%2NAzwTo6mHnXZ)n&77y>b1KX&npO=eJJ#$BaA7j#10 z){HJl-F;~e@yknt+ut*dFw-pkBbpbvc0-Q@!=+LEcD)A@$UZ-VA~Amyj)T7|4m zEL4nHJ5RW$K2DX3GhxekGnoJkj%?g1Ilpz3RTlSqRs5EWApU5mp9_E()ukUw5!Vt* z<0YM{Nzhk*eR0{bP35`f|55&YS+ksntY1wpf3ST>^#P@hjSpZ3<~M3LhjA#;2*GV4&g_n878?q{SrT&G?xeOn<)*qyP_M zIV=}0_;yD;N?b|4pToay?Rdp@8lDND9koRqkqhkPU<_DB?ORCaQ^0_oJYVX*dUPtn z>j}PE9EknIrltNsndP=yO-RdI&C9Erat7e8x$^lWfNgXCJVZiP=euRQ)ZmmQfQjHb zyj!GFnCcFy?0wp~3nM7rx_VyGEKoO!`e0n79#&~A;ao;K{w7w?e~Hz(j7_BNlIte8 z!tVHHizAr%Hy5{TCMmxWms}$9Wfo+trt+k^Cl!KT-I7SvkOp4gCtWf77GouzwiMH& z6OQGd{qIu_rwdyu(3NBv%(=+LKg~?5y=DpswjHk0Wz_4ha}cflB;Y2m5%b+uS-Pjl zZVhN0i;xKAr`yAgk!Ks;MrFOFc2bl1tr26l$Y@xgI%>|xvqI)zW_Fi8t=??;_0>XD z%6#YZ(lQVE1tEZ4e$bB0XSW`l4@%mU}qSY`2s%<823!>Wv&yflgw zY^P2LNt!S#ax(lLwE4Y-Y*hPg<&^E3`QDXEaieLS8R*hDs$zD;uD_prFH@9cTO$2T zFlmwK1vxhV?w-u~S101YVN=j`&$(ddngv?QrA17v+JTX8GWP?u$B{PR(^7n9h;mnw zcZbo1eb?6_ey9wA6!0IJww*_Y_cyu$kCcz-zw?Gclb&r5aM!`)hk?a9nLmm7X-s1X%=)cR~ zmlfd{tKPfFkO*NZZ6re{>P=~}BylY@h_~n)-6PXBM_{gvhrqU4As1!CWHUw8i3xWz z{Jx#g>W`g@x9oTQ<`i7&o+Gy+Sh#Y8k!N$?>Eft;fGwYX`Qh7gYwntjjKnLSop zDPH2coQc{)ibYCr3>6yhSca{pU=ZbGmko&`=4^oZoLlVtxPx(OJn7MwQVU{C6IJh%$p_LFdX8&16|3%F<9<#j$<9&O-WH2~@J9&Y zY;A$1_vfdKSn$2J%Xh@nwEJtc)2Y3gX0y6it>iFBgbPI%kEZBO`U6Iezehad3)r>! zSNc=?;YctJH&7HkpM#0*```*7$%tKxqZ+_WLgUG{VWz2~zI(XXIsedv%X*1`pDBStRz~S+_Zx2;{`g07mhFO=)v^~r9TJRUFE zFUDN+g(&Q068~cbE4K3!^`Q1=$Z=3{w|}=5@y-)U%=+cafq8?<7}|9T-9QM1*oA{cLarC-l^UJ!#vmM~1d_bV1metiFZfihT1v*0(Q zVOQxd^`Sq{4U%iRB#}W!i4TKzs9>)Bccl9{!DB~Uo~eLlLd~cvOf{e4hMV=o0`hpK zqs4$diT=w2XaLH2?k49g>3GXnKp`i+#cELfI{-~>fEmis4Xi@vQ1rR- z_1|euY|RL8hX!{;s_*~*=rWoz#_kZf&ZnVYzv17E2w^fco?g9Qgvb|c+L&RlEZ2D= z-z~G~W}m?kJEy-gCPOV|I)vUux%PKOg<~&(X@=+35`#Zo;^W{aTw$aPS%nLU(8clm z|7bE3J)Oa6(qZWbQ+NF1161aWjEZu*(%X8H$nSz7WYK!_a7B3v{#)HpO8I)lS)UKE z7c$T)PVeEJcYb`JnE4mUQgiQ2$`QSVuW5vsBwt6ojl^|HIFR(LY8Hwsw zRDJMxGPkv@I{6tc_o+)vd>a2;OgWP(!i{v*GNiLTUSK#Lama3eDfL#6(yN%($VCC3 zWF`+?E)mqU;|+s5I1-MaA9fKwVBmgY_}0B?!|R=IRQLCbf%$|U za|+UEFavrbx?A5obNG3fe;hHatty>*zH0g{@y$(jH#eyuHnU~WzaQ((YxkFuiyPy8K> zqSxEKBrUp-23;EPstZGS|6Ono&zC6Jt-rHT+P#&p{AT^g2*seQ{;}vEPWE}}Sn#yB8HXGQ212;0j^kG|#d zcnUz1>WC{6RQK=>bD27kpW~RQ&M*QP=I!n2hrxXccbp0HWu{*vJK~;72NPsJWK@_I zo-6Qw;wz}eFqN4_M+Tq1V)!D0v+ODNs~pF>qJI4M6>wGnBHCKOJ@7MqGSrE9^{?&j zpGRv)mM1Sp=--jPx$5_VseF2lC+jJ9faG$=vJ8kDAU)3;jS<5hZ)PX|E)L=h*{nYC zT;q&?17R(~LZg~oX8}@1SKVp;F51#>W0@#J!WfKk=81pm#-=4(#dY|1EABJb^uodT zoZRLjgN@c2MRzDR;>HPr4?MCsjsw z%{M`7RWaTTDXnL5!TS%!zJW=mIH%7erBo-SLB4`R!$5up+&ysDE}-*QvA}T=RS}%d zolACH?LL5|K8Q(3rBu2!x!Gk5(=B=1~2?qeG`6_#6%yWy|Po@bEtOR*7Xbe|_~W5S7Z- zQ5%)c?AsKs2Jkz@=gyDh886zRtnWRJDVpqvTq%WaKWOjI@>fuPM+Iyv`K|u}oj4LA zUDJlLK?a37b0P~^{wqj*!3ZU~M8)8-OQAE>UQuGCpJ)wt`*vSsgPHLrn25%w@7Co= zRO7Y&IfV0&tvlGaFrU6*+<=WddUogRsgTds+@a2pRcAXZfd;pWLRI|kn^Q{i+-3_> zr`wh4kRml02L}F8z5_sx>W2d}FW34PlK>ibDkl*Yz1^1p+_`FxiyP*Ifyrgs>4=&e z?hA~5_gHR%xp~jPgJXbitKEjpe(rI^@f3*&@Y5aUulyAKpf+rPpA}_2`q;%z|L>K# z1FsLw%pCpt;y@1soSU&6p+K&~+n{skgwtC&j{tfB_?KNbwu2@~t7_4cH2V^(lg@{- zKHsUG39_lys#`DTBElmgp1g4^ufFfn%2osL5tu4M8NSfw_^n??4}9n9BbSAD<-c8K zl0g0RUw(|hayccl=NrBf0pqD~-8P&F6xqRmWtH9fMa8B@&_*OC1&K23F3aq4U{A*Z zspIstit?%i$2~j=#pyqUtmAFDlf zscHUyEnRh3RNdEoO+p$3B&CrQkp@wuQ>0@+K|ma0=pnC2ry>%P0s_(u(j7w%At>G5 zos!=fzaP&7e+DD7THH{t>I@!gV+wFF4}o$n>+@z{!h29r9@gcB}uJN?aY)t z&ofEItIP(bI%6)kmCSgTP{>#m6{)lUodK-RoyY>@E$`tPWK*%mt_B`i zPQ~qa_x>cn*=Nr(Z)?L-40%?rT{#SKOXr4w)T|VAK_$b&s2Hv?$`aVxEZ&@-yW=Hfao90;!G}{C>l?Z z4*H*CH1&tccPTydA2V1`oQ{i^2%#I*_(Yw%0kFSD7{J8|w1&Jbze-U7hb+0P3{iV35==0J)`= z)jQYA)5*#0YD_tJhC}~-@C(TYor_E2Wwpm-i1;l&9{s)WSJ&fQ7VD;DRsQ@O_Z- z)$oFH!`YWPgRhCr!bJ?kcaIE`7di8m#L6j?t|LHoSg4*Z0x<^OyH}HO7*#(WKdR9g zdUI;b?A(mEI#H*#vk*E}E5#pKJzjo#q`+ITk;xsdZdcQX>qWl?g00)QCwCnyc%?)eC zInF#`1rVW~v?k=34h#?uUbVhYFg5&))ZsDbEhvkF@UteG~xc6JYnbMErx3cC>l26a!X$;9}cQbTbru0~=t6Zw)-u z{wh%6@W{)(885m%nU1)6HOo*4XWe2WKl`CTMDlnGLwzebXFm|Iw-h-?N!1hjw~Hq1(})wQcIoRp;mHjWf>L zrQh|tN?um7{-mqBa1}2N52lpV)rCglbb=zA#WiHpt3pN|D_DP5{|si~!NnTT!&l4i zsf|U-fraJ#MK7b$HuTKMPq0t5@2T4u5Kqa5gy}xAIpdkqzw7bGSm91D#{Rxt^};7q zu6K=%2M$x;2QLeXIxWY5_&=m8EU{S{?UOtF@sMri)T~fYI35BO7FLn>ocO*yyS8?+ z(>(cZXH9+h-)~UtU#!h zS^u$)D5fC74qDS3a9N{<*^M|0*6$ODA`S zb21waR9ua9omN-!+ZciMn;#`b1vKf3g);jSx)hCa28xuiQ5CH8@5Ms9;Xu7KHltQt z+XUh~qe)Tu>AaniQm`Q+8}IQC6W=We6cMxTou4~FoAF8ZRQgZ1^xa_YS-wA$%qzW? zf^WCi#}Acm?F1)y?;?JLkGmqP+ z*85S4<`fv5`R-c=u897*w8YCIB@j)6 z=I+fw9cw(Glj4^_D(-FgihZmfvHF!)at>C^fzH?y^J$;A;;p%|JRizmTPQs6c#SQh zq=rG#X2oOh{r`Xgz1mYLFSwfG1$RwMI|bl7z!X|v zF>$=wK|VD1^GFg~M|!|PrG;7gBHBGogf>slgEf5t??hb*%X;a5G2mCRN@CSpa1^)} zjY*?}CXn+HkDOOt09}HFty#T;!!ZxBEwBF(Io2FzQj=X1oPWAy)^K$uEi z3HqnpVM`yVIB%0Po^|i?ki_bBzNY7jz$h^zN&6sZ!3WkzSMKKyYS={9sh#E8|dolYzflB{zVUB!jtj^ zy#}(s!wscxeUZx3dzdiXmVF9ohVmRu{UByxhZKIH6nUH6gK2HbO3^DQk*1FfE~4-{ zV$Su4;YT5s6nhp#+BMHA@%!_t7GTPT=27jHBs$K+>a6oi*HXJB?8)l;ib_A1XT5<* zQFaqjcJ1^lFm`@5CMJDY1PI1C9m-mhZhuz5pHA5K@+5vRjpdz8ERE)V((Yq3t<0+|<~Mi` zB`-{^cS_jb0pVUC2RG=EFNAio@%OzU*8c2{RW5)+mOkm8@7|pPi9p*IEJ;%7B+}4X z(>C)V>CK<=4%|(Tj0-&9^FOLmxUI780Wgw0H2ETT0>9jY48gvk@6btZCF~TJnag0s z=kYt}6C(h`@nA%Yn$-43Eezg}+LnU1kscHv3*#0Y@IuOEa@6GR$o%4I(4VSrFlk24 zx?3H8vefP6Oae>2C#WK+8F&|D+8=U+wa-;iT4W~=oFzQe0?Yycz8wRdis&UplV3iv z(%A0AD;rX7KF%ApqKbxpzt1SKQQSgd^;i&c1|;ruC(UE;Rkl%>w5;mw?Ub{vyy)ET zqLBNNlC)$@twPZ6P~b$in7pDab0gz1AXzacAcmzd_H9&VGN4#K zll&p)ZdFQb4rQVR08D5^a!V&Wt!in4%{_-BOlAcXU-4d>_X6IuiofOMmV|8?qFaEO zBQ;-ce7E_|Dw~YENWAj&+P==?hhaXjAC{NInxJKn$(_lEh`;alI?`FS~3x?WRFY4`{J93w*e?`oyGP#&p*AM zk)O@NPm*j^qoiRo-ae|BV21n87BS*}7Hm#Tdib65^v@x(oKoz&{h?Ow+xz85!)fWJ ziEVI?d!(LK)_MBBhVC@z%Qe(*3=f)RL=2ekPY4dL>LVebdrqugY^E;WdoY8}i@!yw zcj$Djg{PdiNbZhBG(uy{~bYKte$8j8Kn?TLGZ`EPq5Qvx=UE@gMblgAz zY)|+bL5`5f;^oivgBqZkKCD?E`J)Gay!KVtU{rk}rK)aLDpN8MkY*G-oE>1^s>5`j z8stMYb~N?(hIbsxA6bEN>CY@NPw_w%FF<)S-qRv3yme_UYHIe=rphAWec)~P5==AB zC*cn&xi|!h_Ut-g2L(Qkt!c5@>83%UKDPZuf~1wRDRyH-Z{YyL!=piLf<6$Mx#|p$MSOw`ov2=Ysex1C)0s}Xi zN3N4D!-4G69sU^KqiNGHN~C(N=N3?Y8Y8k}kXspI@y_ehWw|z@YnsURVMua4p3l@` zDt}K#KqJD-yP&8i-Ky_E&@hu(9S8J&TGf9TvGDDg^~l4zH|g6X_+RIsZ?$5HWA*VMG< zriI`YhsI5tjhlR)Rg~2mn}$2-2T&~WjDDGnpbD^oG6}y4q_XYU;o}j^r0wsj(q!6X z?@senew(Q86^9<#00I0#I%7WPk=H@iI!S%fSH`(CwJm{!zjeEsa2SoewU2B0)Bc6kJ1mu4^fWo37#d{Fsw-SjvEw4;@1N!dt%m4A`6;hu`KbUs5r^+-< z4lEGEUmwzCnWgEvWbEU$47fX>;xD@0`;S6Lp9mS*DSbSia!nM@@;AcKb>WFH!V~TS zr&eE$Q^yHfT=;7NaJ&uzuyLc!2iH6+HWmZvpxTb_9HRq zMQaLRbB_tIO*~HBxk&ePvmFdtcRYS&Tz1oV3NYl|*hGY16)t80>AKFKs4Drdu-I7h zVcT00f9YiS@n>V|7qj23BM9Xv=CF;<8N!y6+Tb929e{o_S<232nMzfiY@vXXCR`=p zb+;4I>t2c__18pq|K9|LDacDu3Y-;41Dsm>f|vAf)lTDHV#g>mdLrp_#A>Gj2itu_ zRefwCjrQZ6D#*SCvE@jw6Cg(TYSLVuqn4O3t9!|JtuB; zY7Nm@du;h{1FOX~xugr8EKq5`DlhK zy$)ksReRg_d*b}J?{F9XD0ndX%8&4k3SZBIYl4c&J;iQ~UV!!$xE%_1S%33#Vrf9T zGo}-A7%%TJ0Yl*3>*0*#JR+-Oia1CSPJ<*J_A%TpM8 zh!E%@us8^%?VTDum$diuC3_Mio_qu3?fcDa@>dsEo5_UvNjk}G#1|a{FP_SMsquLw z@ZtfFrm{7x#e>k!*o?}Ui6-tXjXOtrEqT3kPpkCZ?{`-lIPUdDklkhXuDgoVPW=fs-V;Kaqai2KJSL! zzg&3~=r(PJ&^Rl+X;^f$Nn>-s9oiz?o>Xb+au2Kdwup!abSe*P22V~-OgYAX_)F7O zwyh&V5{3hN#kqw~73#bgaF!#~~J>t83JSW}ysbHMRQUD(&FtXG23+>O#RB3Cp5#J@1oibKA zeb)Wq*6YQtm|39a9#U8L)BEfQ8TJ>BdPf{>7v6qBIepDC7zAZkw!*c}sc?Kj5*~Epw_kT#u305_FLs~1?GD)YI^i(VZGE)*gsH*BsCx;ez@&T6 z`(cgg=ko$cy@z?a_=5dKFxoIBajbWcMac_<*s5Te2 z=UP%}6Z%W;W&wAA#%gQSg|=4tpykOU@rlLF&l#nzF{j3xPgGiuXVmOVphxGM?6+|O z3aR<*8j`h3;dX2%YA(C2`HvVqW`TYwzEQbN$lw7rE$y9o0WT_k6C2Fmg`au?>{-5^5pRa=vy$_OsYdpE2~%WFGp5 zL>0Gv#!J)Of#q;KBX`9oNmqK0!aa%mQA zwbz~pG1|Fl>K2CMFyAHuPrzrZVLF!N&C&bmt0%5+=v=hlCLN|gK0iL(4Z2K3Brz?6 z^Ac(m#+1`xY*VPnM)2Pz{6D-F>-8em0B)G(WZ4p=9Ar~PY#uA~YC>|lL}Blu&_>O`jLXm266 zKkV?7s)f$U%@If{H?!uco=ukBP^A7(cFHrn^iH!z8B(`0xaVXq z%pFP`X@QlhnAzmuj%i1hC6w5USQsU8jeClDi75mBbB)Y>r#I$ykS-Phe3&l+hv_yM zxOLv6&7TTS#B?f`Q${prF19OFdZRxEl$1_K7^fy*yEEs#BqVS_0B}(VNWQrNdV{2LF#UNO**u6zCjor7 zxC${d$(Uo8dCmgOsrm&n&+9M(K5*j+Ksg9^eK?W9ot1(KnNb+tG-Ag)X(u{AWYn_v zc;TbeP;;t#>{*8#)uC062y=&7Bj`4gIYzIUkz1WSlI;n`nzYay<7zjA3QAHRp>&Ro z!`td;9Tsv}iX0ZoYPfCrjRY!oYbW6*Zqo!5lJurX9r+7d zWp*+jK9Dx4E+wr$tM(c@LEDZui*=JGJ5IVVC3)KMtYwC^BvQ(f^*;@FcGT8cW*$N; zxUBIVePmhFrpzelLQUz8YKXKBO=<~<1FS(QU&szxGpBH`B{H6oy)aeFqh5pHK0b`e z5vlyu&9ev!$)?;LK=h_A_1vlW_%TRgdM|e5UEeJ|*j#hl+VFiKw z{b6M1zXHcEL!9<3%mi-kvoL&}6c}msdE29_8rSJGrFFby7?W>iU0=EXl;QofitAf{n%t%XYvsa>JbroN+ z2pPcJc2!={+UA?xGV5{+_2u@D;VsSrm^EX6K+S+KaMulTP+5hi|CZ8=JS-0_sQQUR zr^!-ukA7=UIE8DI<>{`rwQ0^1%iZ(h-9RxdOTxQ;VPJ6e9SX7{YVWHvlt2u9JN+>3 zG&E^$j-R+lp3sViI!eVBNvVU|dX{GCHj$ zY{j`R#=Ne;jC+gkXvu_4KGm~g@4cM+1ta|bZ`2QrWe3o1HB=av(bOwRS5=Gky~T(f z3%LwI5nFtY?Dgej#D_X&=W}QmC2+Pfx5LGhz{76%T)03YWTiQ37#V|IC1HIz;Cbeh z6qJV6RqKWH*JPA#v0kTCFuA&r?j|0#m;52{I)R#jqFP23hb(0Ez7prqUJuf>>B9~n zAq6bDP176UnV!DHWxPW2Sc=dS6_J^75RcZv$fSc!AjmjL+cWdh@{|pE|HDPtjCS(fH!1uXGOGU*&F_Bh}er_6J z*70Hmzn@zY@EtW%>kd+>yj52qbi&C&8vrGAT=nw(uE5s_7-sh*0%oM|aoZ!$wi2w50gSa;5Kw{KKCpKah4qnuq$ zm?&%xqP6JFP)%j>SR@}ti^CBJ;x5VA9m}Lwy>cdZ%-BQq>be*REf3R~?n~El@yO)L zvCekDCt@l>{;fNC*-TF*A|WXv7bTm)$yQv1Y{USKgLWlm9ITAbkykbD5h|x)R8V_U zNSZ9L_i|~-Xftpngd-3!YJoDZ+-Wg?*GYzsl~c?MW}2j4mEqv#o|w@Bn^LFGbjihB?SI=reQfm&Ns~+CmX#i<5xJ?$Zdl4G97s&`F&eoA zS}EFZblgwjk>`2p5LcnK%?gz-o3MppN^*-eFeL@Ctv@CtLNa>kGlj%27?&TXR7lJP zi#`-6<#Y}pk=pNI5zbpYJ!IOLxMv8yL|s+(MN9?xxC00Sl5@e;$~q(27NfdGeaL&H zk+p5(AsI!EvURU!C)x_G+!`c^lnI1D;6aDamc7|Jc9eFUt{)MALRupOxc6ujtYKuk zv7UU)19hwjjajWm6|?oNDr(r)Cc3|3Ung(lBbC58){3);MEmlyI-_!Q8!M#*WpOY~ zri&8VXp4F337L@_e~2bnmyvV|CN)1frQ+7~@`L?IpMR9m!$q0S>IxsT z8_4YV;+QF*p}8!fx4*@yP_Ytw3HoSQY2MAP2VVHd7@PHiSq!cNh^=hyjp?Ob#jZ12Pb|XkqprPv&i)kufX4%8|w_8-0X(sa) zz6+&_{?Rex-(vf#NLmIm6k?MnPRLWw!!`ZjsAp;1{y%Q958i*XRe8}$E!Fdjtz<`g zDyV|If5n82qu?((t&q&qLBT{2Ifb*D(G-ONX`Z1Z;ogFTe$T63|=>)9Q>B;#lN&Q|7FdM8(f6-T7 z$2Ak%-U8>_5tPMfNPBHlmbDs8naU1tV;*{HV!ZQ)u!|4h@?lYhp1=ANF=2E^+ONAZ zbT3kT#QlpPDgV5y^;Se5Ojbt_@tcO!4;WWORv9;A^jDC_cUlLFF*xPyV|OTowXiat`fD#s{|8))kPG%XBLX+b{Xp z<5rwAMp<49V=3BobsQL*r6qEaKLXBQ6h~*;zVAzsOT^@~)utWgo6PZgf&@q( zFryj3Tmm|g$v4okXTyH-Nc?T|>LtM+yOU-rnG-aJ8Ivq_-l!E*Ji4}`9UJ2A6@jh?)**8{QCuwu&$B2%+fgaI^aA`#X5o6XUCfN_z8+6{7nlzRH@O^WI z9L_HHGNq=xxF~x z)KIn8MZ#BkpHhYbYpDEn_TQDWw`-<7k0((X#I^JEuDTZ`ajk(Qx4=qcv1Z<3XHb1-fKDFK4|~_%c_qdQQMCr8QO~;5m0+_Tt&iHFN)hw3N{fL)jf=9 zV6k2D=glADV*FB&%>Ey}SpD+~Lunat1qgw`;4hHs<`aX~w3uplBT&zSt-nR{ l)QLuO*NOe_mzDDJ`qQ2;)c`J;h5x{hlAOA1q0Flf{|DAcpGE)x diff --git a/wrench/reftests/transforms/reftest.list b/wrench/reftests/transforms/reftest.list index 3630e6bb31..88727f025c 100644 --- a/wrench/reftests/transforms/reftest.list +++ b/wrench/reftests/transforms/reftest.list @@ -24,7 +24,7 @@ platform(linux,mac) fuzzy(1,283) == near-plane-clip.yaml near-plane-clip.png platform(linux,mac) == perspective-mask.yaml perspective-mask.png == rotate-clip.yaml rotate-clip-ref.yaml == clip-translate.yaml clip-translate-ref.yaml -platform(linux,mac) == perspective-clip.yaml perspective-clip.png +platform(linux,mac) fuzzy(1,1) == perspective-clip.yaml perspective-clip.png platform(linux,mac) fuzzy(1,2) == perspective-clip-1.yaml perspective-clip-1.png platform(linux,mac) fuzzy(1,2) == perspective-shadow.yaml perspective-shadow.png # The ref YAML here produces significantly worse quality diff --git a/wrench/reftests/transforms/rotated-clip-large.png b/wrench/reftests/transforms/rotated-clip-large.png index 1accf1b65764851559be6e9631d9c1eb45c43f5d..a9c0efbe00324f94a47c77e0869ac7748e476174 100644 GIT binary patch literal 7424 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 literal 7433 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 From c8a74fb8a9e067ad5ebd3aff60175d3af5c29ce9 Mon Sep 17 00:00:00 2001 From: Andrew Osmond Date: Tue, 24 Mar 2020 09:39:38 +0000 Subject: [PATCH 4/4] Bug 1622254 - Match repeating tile sizes more aggresively to their snapped bounds. r=kvark When we calculate the repeating tile size, errors can be introduced, such that there are cases it should be the same as the bounds, but is slightly different. This can cause a new repetition where we did not expect one. This patch makes the comparison when may force the tile size to be the same as the snapped bounds more fuzzy. Differential Revision: https://phabricator.services.mozilla.com/D67620 [ghsync] From https://hg.mozilla.org/mozilla-central/rev/93cf130f59f97acc6ebb84c3505880cdcaca36c0 --- webrender/src/scene_building.rs | 13 +++++++++++-- .../gradient/linear-adjust-tile-size-ref.yaml | 9 +++++++++ .../reftests/gradient/linear-adjust-tile-size.yaml | 10 ++++++++++ wrench/reftests/gradient/reftest.list | 2 ++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml create mode 100644 wrench/reftests/gradient/linear-adjust-tile-size.yaml diff --git a/webrender/src/scene_building.rs b/webrender/src/scene_building.rs index b39dd8e86a..ee9842f9ad 100644 --- a/webrender/src/scene_building.rs +++ b/webrender/src/scene_building.rs @@ -41,6 +41,7 @@ use crate::resource_cache::{FontInstanceMap, ImageRequest}; use crate::scene::{Scene, BuiltScene, SceneStats, StackingContextHelpers}; use crate::scene_builder_thread::Interners; use crate::spatial_node::{StickyFrameInfo, ScrollFrameKind}; +use euclid::approxeq::ApproxEq; use std::{f32, mem, usize, ops}; use std::collections::vec_deque::VecDeque; use std::sync::Arc; @@ -4087,13 +4088,21 @@ fn process_repeat_size( unsnapped_rect: &LayoutRect, repeat_size: LayoutSize, ) -> LayoutSize { + // FIXME(aosmond): The tile size is calculated based on several parameters + // during display list building. It may produce a slightly different result + // than the bounds due to floating point error accumulation, even though in + // theory they should be the same. We do a fuzzy check here to paper over + // that. It may make more sense to push the original parameters into scene + // building and let it do a saner calculation with more information (e.g. + // the snapped values). + const EPSILON: f32 = 0.001; LayoutSize::new( - if repeat_size.width == unsnapped_rect.size.width { + if repeat_size.width.approx_eq_eps(&unsnapped_rect.size.width, &EPSILON) { snapped_rect.size.width } else { repeat_size.width }, - if repeat_size.height == unsnapped_rect.size.height { + if repeat_size.height.approx_eq_eps(&unsnapped_rect.size.height, &EPSILON) { snapped_rect.size.height } else { repeat_size.height diff --git a/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml b/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml new file mode 100644 index 0000000000..c9145fc5e6 --- /dev/null +++ b/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml @@ -0,0 +1,9 @@ +--- +root: + items: + - type: gradient + bounds: 15.47998046875 18 684.39990234375 643.199951171875 + start: 10.286011695861816 653.47998046875 + end: 143.13165283203125 520.7279663085938 + stops: [0.0, red, 1.0, blue] + repeat: true diff --git a/wrench/reftests/gradient/linear-adjust-tile-size.yaml b/wrench/reftests/gradient/linear-adjust-tile-size.yaml new file mode 100644 index 0000000000..4d78b9b99e --- /dev/null +++ b/wrench/reftests/gradient/linear-adjust-tile-size.yaml @@ -0,0 +1,10 @@ +--- +root: + items: + - type: gradient + bounds: 15.47998046875 18 684.39990234375 643.199951171875 + tile-size: 684.4000244140625 643.2000122070313 + start: 10.286011695861816 653.47998046875 + end: 143.13165283203125 520.7279663085938 + stops: [0.0, red, 1.0, blue] + repeat: true diff --git a/wrench/reftests/gradient/reftest.list b/wrench/reftests/gradient/reftest.list index 79fef2120c..ac0b6454b4 100644 --- a/wrench/reftests/gradient/reftest.list +++ b/wrench/reftests/gradient/reftest.list @@ -73,6 +73,8 @@ fuzzy(1,3) == tiling-conic-3.yaml tiling-conic-3-ref.yaml == radial-zero-size-2.yaml radial-zero-size-ref.yaml == radial-zero-size-3.yaml radial-zero-size-ref.yaml +== linear-adjust-tile-size.yaml linear-adjust-tile-size-ref.yaml + platform(linux,mac) == linear-aligned-border-radius.yaml linear-aligned-border-radius.png platform(linux,mac) == repeat-border-radius.yaml repeat-border-radius.png