From de7aaa25a3513aed308f3e7938b63c2b8b5eabb5 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Wed, 11 Jun 2008 18:03:03 +0200 Subject: [PATCH] Simplify ActiveSupport::Multibyte and make it run on Ruby 1.9. * Unicode methods are now defined directly on Chars instead of a handler * Updated Unicode database to Unicode 5.1.0 * Improved documentation --- activesupport/bin/generate_tables | 147 ++++ .../lib/active_support/core_ext/string.rb | 6 +- .../active_support/core_ext/string/multibyte.rb | 81 ++ .../lib/active_support/core_ext/string/unicode.rb | 66 -- activesupport/lib/active_support/multibyte.rb | 36 +- .../lib/active_support/multibyte/chars.rb | 782 ++++++++++++++++---- .../lib/active_support/multibyte/exceptions.rb | 7 + .../multibyte/generators/generate_tables.rb | 149 ---- .../multibyte/handlers/passthru_handler.rb | 9 - .../multibyte/handlers/utf8_handler.rb | 564 -------------- .../multibyte/handlers/utf8_handler_proc.rb | 43 -- .../active_support/multibyte/unicode_database.rb | 71 ++ .../lib/active_support/values/unicode_tables.dat | Bin 656156 -> 710734 bytes activesupport/test/abstract_unit.rb | 8 +- activesupport/test/multibyte_chars_test.rb | 642 ++++++++++++---- activesupport/test/multibyte_conformance.rb | 101 +-- activesupport/test/multibyte_handler_test.rb | 372 ---------- .../test/multibyte_unicode_database_test.rb | 28 + 18 files changed, 1562 insertions(+), 1550 deletions(-) create mode 100755 activesupport/bin/generate_tables create mode 100644 activesupport/lib/active_support/core_ext/string/multibyte.rb delete mode 100644 activesupport/lib/active_support/core_ext/string/unicode.rb create mode 100644 activesupport/lib/active_support/multibyte/exceptions.rb delete mode 100755 activesupport/lib/active_support/multibyte/generators/generate_tables.rb delete mode 100644 activesupport/lib/active_support/multibyte/handlers/passthru_handler.rb delete mode 100644 activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb delete mode 100644 activesupport/lib/active_support/multibyte/handlers/utf8_handler_proc.rb create mode 100644 activesupport/lib/active_support/multibyte/unicode_database.rb delete mode 100644 activesupport/test/multibyte_handler_test.rb create mode 100644 activesupport/test/multibyte_unicode_database_test.rb diff --git a/activesupport/bin/generate_tables b/activesupport/bin/generate_tables new file mode 100755 index 0000000..f8e0321 --- /dev/null +++ b/activesupport/bin/generate_tables @@ -0,0 +1,147 @@ +#!/usr/bin/env ruby + +begin + $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib')) + require 'active_support' +rescue IOError +end + +require 'open-uri' +require 'tmpdir' + +module ActiveSupport + module Multibyte + class UnicodeDatabase + def load; end + end + + class UnicodeDatabaseGenerator + BASE_URI = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd/" + SOURCES = { + :codepoints => BASE_URI + 'UnicodeData.txt', + :composition_exclusion => BASE_URI + 'CompositionExclusions.txt', + :grapheme_break_property => BASE_URI + 'auxiliary/GraphemeBreakProperty.txt', + :cp1252 => 'http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' + } + + def initialize + @ucd = UnicodeDatabase.new + + default = Codepoint.new + default.combining_class = 0 + default.uppercase_mapping = 0 + default.lowercase_mapping = 0 + @ucd.codepoints = Hash.new(default) + end + + def parse_codepoints(line) + codepoint = Codepoint.new + raise "Could not parse input." unless line =~ /^ + ([0-9A-F]+); # code + ([^;]+); # name + ([A-Z]+); # general category + ([0-9]+); # canonical combining class + ([A-Z]+); # bidi class + (<([A-Z]*)>)? # decomposition type + ((\ ?[0-9A-F]+)*); # decompomposition mapping + ([0-9]*); # decimal digit + ([0-9]*); # digit + ([^;]*); # numeric + ([YN]*); # bidi mirrored + ([^;]*); # unicode 1.0 name + ([^;]*); # iso comment + ([0-9A-F]*); # simple uppercase mapping + ([0-9A-F]*); # simple lowercase mapping + ([0-9A-F]*)$/ix # simple titlecase mapping + codepoint.code = $1.hex + #codepoint.name = $2 + #codepoint.category = $3 + codepoint.combining_class = Integer($4) + #codepoint.bidi_class = $5 + codepoint.decomp_type = $7 + codepoint.decomp_mapping = ($8=='') ? nil : $8.split.collect { |element| element.hex } + #codepoint.bidi_mirrored = ($13=='Y') ? true : false + codepoint.uppercase_mapping = ($16=='') ? 0 : $16.hex + codepoint.lowercase_mapping = ($17=='') ? 0 : $17.hex + #codepoint.titlecase_mapping = ($18=='') ? nil : $18.hex + @ucd.codepoints[codepoint.code] = codepoint + end + + def parse_grapheme_break_property(line) + if line =~ /^([0-9A-F\.]+)\s*;\s*([\w]+)\s*#/ + type = $2.downcase.intern + @ucd.boundary[type] ||= [] + if $1.include? '..' + parts = $1.split '..' + @ucd.boundary[type] << (parts[0].hex..parts[1].hex) + else + @ucd.boundary[type] << $1.hex + end + end + end + + def parse_composition_exclusion(line) + if line =~ /^([0-9A-F]+)/i + @ucd.composition_exclusion << $1.hex + end + end + + def parse_cp1252(line) + if line =~ /^([0-9A-Fx]+)\s([0-9A-Fx]+)/i + @ucd.cp1252[$1.hex] = $2.hex + end + end + + def create_composition_map + @ucd.codepoints.each do |_, cp| + if !cp.nil? and cp.combining_class == 0 and cp.decomp_type.nil? and !cp.decomp_mapping.nil? and cp.decomp_mapping.length == 2 and @ucd.codepoints[cp.decomp_mapping[0]].combining_class == 0 and !@ucd.composition_exclusion.include?(cp.code) + @ucd.composition_map[cp.decomp_mapping[0]] ||= {} + @ucd.composition_map[cp.decomp_mapping[0]][cp.decomp_mapping[1]] = cp.code + end + end + end + + def normalize_boundary_map + @ucd.boundary.each do |k,v| + if [:lf, :cr].include? k + @ucd.boundary[k] = v[0] + end + end + end + + def parse + SOURCES.each do |type, url| + filename = File.join(Dir.tmpdir, "#{url.split('/').last}") + unless File.exist?(filename) + $stderr.puts "Downloading #{url.split('/').last}" + File.open(filename, 'wb') do |target| + open(url) do |source| + source.each_line { |line| target.write line } + end + end + end + File.open(filename) do |file| + file.each_line { |line| send "parse_#{type}".intern, line } + end + end + create_composition_map + normalize_boundary_map + end + + def dump_to(filename) + File.open(filename, 'wb') do |f| + f.write Marshal.dump([@ucd.codepoints, @ucd.composition_exclusion, @ucd.composition_map, @ucd.boundary, @ucd.cp1252]) + end + end + end + end +end + +if __FILE__ == $0 + filename = ActiveSupport::Multibyte::UnicodeDatabase.filename + generator = ActiveSupport::Multibyte::UnicodeDatabaseGenerator.new + generator.parse + print "Writing to: #{filename}" + generator.dump_to filename + puts " (#{File.size(filename)} bytes)" +end diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb index 7ff2f11..16c544a 100644 --- a/activesupport/lib/active_support/core_ext/string.rb +++ b/activesupport/lib/active_support/core_ext/string.rb @@ -1,9 +1,11 @@ +# encoding: utf-8 + require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/string/conversions' require 'active_support/core_ext/string/access' require 'active_support/core_ext/string/starts_ends_with' require 'active_support/core_ext/string/iterators' -require 'active_support/core_ext/string/unicode' +require 'active_support/core_ext/string/multibyte' require 'active_support/core_ext/string/xchar' require 'active_support/core_ext/string/filters' require 'active_support/core_ext/string/behavior' @@ -15,6 +17,6 @@ class String #:nodoc: include ActiveSupport::CoreExtensions::String::Inflections include ActiveSupport::CoreExtensions::String::StartsEndsWith include ActiveSupport::CoreExtensions::String::Iterators - include ActiveSupport::CoreExtensions::String::Unicode include ActiveSupport::CoreExtensions::String::Behavior + include ActiveSupport::CoreExtensions::String::Multibyte end diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb new file mode 100644 index 0000000..5a2dc36 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -0,0 +1,81 @@ +# encoding: utf-8 + +module ActiveSupport #:nodoc: + module CoreExtensions #:nodoc: + module String #:nodoc: + # Implements multibyte methods for easier access to multibyte characters in a String instance. + module Multibyte + unless '1.9'.respond_to?(:force_encoding) + # +mb_chars+ is a multibyte safe proxy method for string methods. + # + # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which + # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy + # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsuled string. + # + # name = 'Claus Müller' + # name.reverse #=> "rell??M sualC" + # name.length #=> 13 + # + # name.mb_chars.reverse.to_s #=> "rellüM sualC" + # name.mb_chars.length #=> 12 + # + # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware so we don't need + # a proxy class any more. This means that +mb_chars+ makes it easier to write code that runs on multiple Ruby + # versions. + # + # == Method chaining + # + # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows + # method chaining on the result of any of these methods. + # + # name.mb_chars.reverse.length #=> 12 + # + # == Interoperability and configuration + # + # The Char object tries to be as interchangeable with String objects as possible: sorting and comparing between + # String and Char work like expected. The bang! methods change the internal string representation in the Chars + # object. Interoperability problems can be resolved easily with a +to_s+ call. + # + # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For + # information about how to change the default Multibyte behaviour, see ActiveSupport::Multibyte. + def mb_chars + if ActiveSupport::Multibyte.proxy_class.wants?(self) + ActiveSupport::Multibyte.proxy_class.new(self) + else + self + end + end + + # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have + # them), returns false otherwise. + def is_utf8? + ActiveSupport::Multibyte::Chars.consumes?(self) + end + + unless '1.8.7 and later'.respond_to?(:chars) + alias chars mb_chars + end + else + # In Ruby 1.9 and newer +mb_chars+ returns self. In Ruby 1.8 and older +mb_chars+ creates and returns an + # Unicode safe proxy for string operations, this makes it easier to write code that runs on multiple Ruby + # versions. + def mb_chars + self + end + + # Returns true if the string has valid UTF-8 encoding. + def is_utf8? + case encoding + when Encoding::UTF_8 + valid_encoding? + when Encoding::ASCII_8BIT, Encoding::US_ASCII + dup.force_encoding(Encoding::UTF_8).valid_encoding? + else + false + end + end + end + end + end + end +end diff --git a/activesupport/lib/active_support/core_ext/string/unicode.rb b/activesupport/lib/active_support/core_ext/string/unicode.rb deleted file mode 100644 index 666f7bc..0000000 --- a/activesupport/lib/active_support/core_ext/string/unicode.rb +++ /dev/null @@ -1,66 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module String #:nodoc: - # Define methods for handling unicode data. - module Unicode - def self.append_features(base) - if '1.8.7 and later'.respond_to?(:chars) - base.class_eval { remove_method :chars } - end - super - end - - unless '1.9'.respond_to?(:force_encoding) - # +chars+ is a Unicode safe proxy for string methods. It creates and returns an instance of the - # ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all - # the String methods are defined on this proxy class. Undefined methods are forwarded to String, so all of the - # string overrides can also be called through the +chars+ proxy. - # - # name = 'Claus Müller' - # name.reverse # => "rell??M sualC" - # name.length # => 13 - # - # name.chars.reverse.to_s # => "rellüM sualC" - # name.chars.length # => 12 - # - # - # All the methods on the chars proxy which normally return a string will return a Chars object. This allows - # method chaining on the result of any of these methods. - # - # name.chars.reverse.length # => 12 - # - # The Char object tries to be as interchangeable with String objects as possible: sorting and comparing between - # String and Char work like expected. The bang! methods change the internal string representation in the Chars - # object. Interoperability problems can be resolved easily with a +to_s+ call. - # - # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars and - # ActiveSupport::Multibyte::Handlers::UTF8Handler. - def chars - ActiveSupport::Multibyte::Chars.new(self) - end - - # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have - # them), returns false otherwise. - def is_utf8? - ActiveSupport::Multibyte::Handlers::UTF8Handler.consumes?(self) - end - else - def chars #:nodoc: - self - end - - def is_utf8? #:nodoc: - case encoding - when Encoding::UTF_8 - valid_encoding? - when Encoding::ASCII_8BIT - dup.force_encoding('UTF-8').valid_encoding? - else - false - end - end - end - end - end - end -end diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb index 27c0d18..63c0d50 100644 --- a/activesupport/lib/active_support/multibyte.rb +++ b/activesupport/lib/active_support/multibyte.rb @@ -1,9 +1,33 @@ -module ActiveSupport +# encoding: utf-8 + +require 'active_support/multibyte/chars' +require 'active_support/multibyte/exceptions' +require 'active_support/multibyte/unicode_database' + +module ActiveSupport #:nodoc: module Multibyte #:nodoc: - DEFAULT_NORMALIZATION_FORM = :kc + # A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more + # information about normalization. NORMALIZATIONS_FORMS = [:c, :kc, :d, :kd] - UNICODE_VERSION = '5.0.0' - end -end -require 'active_support/multibyte/chars' + # The Unicode version that is supported by the implementation + UNICODE_VERSION = '5.1.0' + + # The default normalization used for operations that require normalization. It can be set to any of the + # normalizations in NORMALIZATIONS_FORMS. + # + # Example: + # ActiveSupport::Multibyte.default_normalization_form = :c + mattr_accessor :default_normalization_form + self.default_normalization_form = :kc + + # The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy + # class so you can support other encodings. See the ActiveSupport::Multibyte::Chars implementation for + # an example how to do this. + # + # Example: + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + mattr_accessor :proxy_class + self.proxy_class = ActiveSupport::Multibyte::Chars + end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index de2c83f..c05419b 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -1,142 +1,670 @@ -require 'active_support/multibyte/handlers/utf8_handler' -require 'active_support/multibyte/handlers/passthru_handler' - -# Encapsulates all the functionality related to the Chars proxy. -module ActiveSupport::Multibyte #:nodoc: - # Chars enables you to work transparently with multibyte encodings in the Ruby String class without having extensive - # knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an - # encoding safe manner. All the normal String methods are also implemented on the proxy. - # - # String methods are proxied through the Chars object, and can be accessed through the +chars+ method. Methods - # which would normally return a String object now return a Chars object so methods can be chained. - # - # "The Perfect String ".chars.downcase.strip.normalize # => "the perfect string" - # - # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. - # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them. - # - # bad.explicit_checking_method "T".chars.downcase.to_s - # - # The actual operations on the string are delegated to handlers. Theoretically handlers can be implemented for - # any encoding, but the default handler handles UTF-8. This handler is set during initialization, if you want to - # use you own handler, you can set it on the Chars class. Look at the UTF8Handler source for an example how to - # implement your own handler. If you your own handler to work on anything but UTF-8 you probably also - # want to override Chars#handler. - # - # ActiveSupport::Multibyte::Chars.handler = MyHandler - # - # Note that a few methods are defined on Chars instead of the handler because they are defined on Object or Kernel - # and method_missing can't catch them. - class Chars - - attr_reader :string # The contained string - alias_method :to_s, :string - - include Comparable - - # The magic method to make String and Chars comparable - def to_str - # Using any other ways of overriding the String itself will lead you all the way from infinite loops to - # core dumps. Don't go there. - @string - end +# encoding: utf-8 + +module ActiveSupport #:nodoc: + module Multibyte #:nodoc: + # Chars enables you to work transparently with multibyte encodings in the Ruby String class without having extensive + # knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an + # encoding safe manner. All the normal String methods are also implemented on the proxy. + # + # String methods are proxied through the Chars object, and can be accessed through the +mb_chars+ method. Methods + # which would normally return a String object now return a Chars object so methods can be chained. + # + # "The Perfect String ".chars.downcase.strip.normalize #=> "the perfect string" + # + # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. + # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them. + # + # bad.explicit_checking_method "T".chars.downcase.to_s + # + # The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different + # encodings you can write your own multibyte string handler and configure it through + # ActiveSupport::Multibyte.proxy_class. + # + # class CharsForUTF32 + # def size + # @wrapped_string.size / 4 + # end + # + # def self.accepts?(string) + # string.length % 4 == 0 + # end + # end + # + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + class Chars + # Hangul character boundaries and properties + HANGUL_SBASE = 0xAC00 + HANGUL_LBASE = 0x1100 + HANGUL_VBASE = 0x1161 + HANGUL_TBASE = 0x11A7 + HANGUL_LCOUNT = 19 + HANGUL_VCOUNT = 21 + HANGUL_TCOUNT = 28 + HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT + HANGUL_SCOUNT = 11172 + HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT + HANGUL_JAMO_FIRST = 0x1100 + HANGUL_JAMO_LAST = 0x11FF + + # All the unicode whitespace + UNICODE_WHITESPACE = [ + (0x0009..0x000D).to_a, # White_Space # Cc [5] .. + 0x0020, # White_Space # Zs SPACE + 0x0085, # White_Space # Cc + 0x00A0, # White_Space # Zs NO-BREAK SPACE + 0x1680, # White_Space # Zs OGHAM SPACE MARK + 0x180E, # White_Space # Zs MONGOLIAN VOWEL SEPARATOR + (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE + 0x2028, # White_Space # Zl LINE SEPARATOR + 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR + 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE + 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE + 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE + ].flatten.freeze + + # BOM (byte order mark) can also be seen as whitespace, it's a non-rendering character used to distinguish + # between little and big endian. This is not an issue in utf-8, so it must be ignored. + UNICODE_LEADERS_AND_TRAILERS = UNICODE_WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM + + # Returns a regular expression pattern that matches the passed Unicode codepoints + def self.codepoints_to_pattern(array_of_codepoints) #:nodoc: + array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|') + end + UNICODE_TRAILERS_PAT = /(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+\Z/ + UNICODE_LEADERS_PAT = /\A(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+/ + + # Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site) + UTF8_PAT = /\A(?: + [\x00-\x7f] | + [\xc2-\xdf] [\x80-\xbf] | + \xe0 [\xa0-\xbf] [\x80-\xbf] | + [\xe1-\xef] [\x80-\xbf] [\x80-\xbf] | + \xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] | + [\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] | + \xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf] + )*\z/xn + + attr_reader :wrapped_string + alias to_s wrapped_string + alias to_str wrapped_string + + # Creates a new Chars instance. +string+ is the wrapped string. + if '1.9'.respond_to?(:force_encoding) + def initialize(string) + @wrapped_string = string + @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? + end + else + def initialize(string) + @wrapped_string = string + end + end + + # Forward all undefined methods to the wrapped string. + def method_missing(method, *args, &block) + if method.to_s =~ /!$/ + @wrapped_string.__send__(method, *args, &block) + self + else + chars(@wrapped_string.__send__(method, *args, &block)) + end + end + + # Returns +true+ if _obj_ responds to the given method. Private methods are included in the search + # only if the optional second parameter evaluates to +true+. + def respond_to?(method, include_private=false) + super || @wrapped_string.respond_to?(method, include_private) || false + end + + # Enable more predictable duck-typing on String-like classes. See Object#acts_like?. + def acts_like_string? + true + end + + # Returns +true+ if the Chars class can and should act as a proxy for the string +string+. Returns + # +false+ otherwise. + def self.wants?(string) + RUBY_VERSION < '1.9' && $KCODE == 'UTF8' && consumes?(string) + end - # Make duck-typing with String possible - def respond_to?(method, include_priv = false) - super || @string.respond_to?(method, include_priv) || - handler.respond_to?(method, include_priv) || - (method.to_s =~ /(.*)!/ && handler.respond_to?($1, include_priv)) || + # Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise. + def self.consumes?(string) + # Unpack is a little bit faster than regular expressions. + string.unpack('U*') + true + rescue ArgumentError false - end + end - # Enable more predictable duck-typing on String-like classes. See Object#acts_like?. - def acts_like_string? - true - end + include Comparable - # Create a new Chars instance. - def initialize(str) - @string = str.respond_to?(:string) ? str.string : str - end - - # Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the - # object on the right side of the operation. It accepts any object that implements +to_s+. See String.<=> - # for more details. - def <=>(other); @string <=> other.to_s; end - - # Works just like String#split, with the exception that the items in the resulting list are Chars - # instances instead of String. This makes chaining methods easier. - def split(*args) - @string.split(*args).map { |i| i.chars } - end - - # Gsub works exactly the same as gsub on a normal string. - def gsub(*a, &b); @string.gsub(*a, &b).chars; end - - # Like String.=~ only it returns the character offset (in codepoints) instead of the byte offset. - def =~(other) - handler.translate_offset(@string, @string =~ other) - end - - # Try to forward all undefined methods to the handler, when a method is not defined on the handler, send it to - # the contained string. Method_missing is also responsible for making the bang! methods destructive. - def method_missing(m, *a, &b) - begin - # Simulate methods with a ! at the end because we can't touch the enclosed string from the handlers. - if m.to_s =~ /^(.*)\!$/ && handler.respond_to?($1) - result = handler.send($1, @string, *a, &b) - if result == @string - result = nil + # Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the + # object on the right side of the operation. It accepts any object that implements +to_s+. See String.<=> + # for more details. + # + # Example: + # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1 + def <=>(other) + @wrapped_string <=> other.to_s + end + + # Returns a new Chars object containing the other object concatenated to the string. + # + # Example: + # ('Café'.mb_chars + ' périferôl').to_s #=> "Café périferôl" + def +(other) + self << other + end + + # Like String.=~ only it returns the character offset (in codepoints) instead of the byte offset. + # + # Example: + # 'Café périferôl'.mb_chars =~ /ô/ #=> 12 + def =~(other) + translate_offset(@wrapped_string =~ other) + end + + # Works just like String#split, with the exception that the items in the resulting list are Chars + # instances instead of String. This makes chaining methods easier. + # + # Example: + # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } #=> ["CAF", " P", "RIFERÔL"] + def split(*args) + @wrapped_string.split(*args).map { |i| i.mb_chars } + end + + # Inserts the passed string at specified codepoint offsets + # + # Example: + # 'Café'.mb_chars.insert(4, ' périferôl').to_s #=> "Café périferôl" + def insert(offset, fragment) + unpacked = self.class.u_unpack(@wrapped_string) + unless offset > unpacked.length + @wrapped_string.replace( + self.class.u_unpack(@wrapped_string).insert(offset, *self.class.u_unpack(fragment)).pack('U*') + ) + else + raise IndexError, "index #{offset} out of string" + end + self + end + + # Returns true if contained string contains +other+. Returns false otherwise. + # + # Example: + # 'Café'.mb_chars.include?('é') #=> true + def include?(other) + # We have to redefine this method because Enumerable defines it. + @wrapped_string.include?(other) + end + + # Returns the position of the passed argument in the string, counting in codepoints + # + # Example: + # 'Café périferôl'.mb_chars.index('ô') #=> 12 + def index(*args) + index = @wrapped_string.index(*args) + index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil + end + + # Works just like the indexed replace method on string, except instead of byte offsets you specify + # character offsets. + # + # Example: + # + # s = "Müller" + # s.chars[2] = "e" # Replace character with offset 2 + # s + # #=> "Müeler" + # + # s = "Müller" + # s.chars[1, 2] = "ö" # Replace 2 characters at character offset 1 + # s + # #=> "Möler" + def []=(*args) + replace_by = args.pop + # Indexed replace with regular expressions already works + if args.first.is_a?(Regexp) + @wrapped_string[*args] = replace_by + else + result = self.class.u_unpack(@wrapped_string) + if args[0].is_a?(Fixnum) + raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length + min = args[0] + max = args[1].nil? ? min : (min + args[1] - 1) + range = Range.new(min, max) + replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum) + elsif args.first.is_a?(Range) + raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length + range = args[0] else - @string.replace result + needle = args[0].to_s + min = index(needle) + max = min + self.class.u_unpack(needle).length - 1 + range = Range.new(min, max) end - elsif handler.respond_to?(m) - result = handler.send(m, @string, *a, &b) - else - result = @string.send(m, *a, &b) + result[range] = self.class.u_unpack(replace_by) + @wrapped_string.replace(result.pack('U*')) end - rescue Handlers::EncodingError - @string.replace handler.tidy_bytes(@string) - retry + self end - - if result.kind_of?(String) - result.chars - else - result + + # Works just like String#rjust, only integer specifies characters instead of bytes. + # + # Example: + # + # "¾ cup".chars.rjust(8).to_s + # #=> " ¾ cup" + # + # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace + # #=> "   ¾ cup" + def rjust(integer, padstr=' ') + justify(integer, :right, padstr) end - end - - # Set the handler class for the Char objects. - def self.handler=(klass) - @@handler = klass - end - # Returns the proper handler for the contained string depending on $KCODE and the encoding of the string. This - # method is used internally to always redirect messages to the proper classes depending on the context. - def handler - if utf8_pragma? - @@handler - else - ActiveSupport::Multibyte::Handlers::PassthruHandler + # Works just like String#ljust, only integer specifies characters instead of bytes. + # + # Example: + # + # "¾ cup".chars.rjust(8).to_s + # #=> "¾ cup " + # + # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace + # #=> "¾ cup   " + def ljust(integer, padstr=' ') + justify(integer, :left, padstr) + end + + # Works just like String#center, only integer specifies characters instead of bytes. + # + # Example: + # + # "¾ cup".chars.center(8).to_s + # #=> " ¾ cup " + # + # "¾ cup".chars.center(8, " ").to_s # Use non-breaking whitespace + # #=> " ¾ cup  " + def center(integer, padstr=' ') + justify(integer, :center, padstr) end - end - private + # Strips entire range of Unicode whitespace from the right of the string. + def rstrip + chars(@wrapped_string.gsub(UNICODE_TRAILERS_PAT, '')) + end + + # Strips entire range of Unicode whitespace from the left of the string. + def lstrip + chars(@wrapped_string.gsub(UNICODE_LEADERS_PAT, '')) + end + + # Strips entire range of Unicode whitespace from the right and left of the string. + def strip + rstrip.lstrip + end + + # Returns the number of codepoints in the string + def size + self.class.u_unpack(@wrapped_string).size + end + alias_method :length, :size - # +utf8_pragma+ checks if it can send this string to the handlers. It makes sure @string isn't nil and $KCODE is - # set to 'UTF8'. - def utf8_pragma? - !@string.nil? && ($KCODE == 'UTF8') + # Reverses all characters in the string + # + # Example: + # 'Café'.mb_chars.reverse.to_s #=> 'éfaC' + def reverse + chars(self.class.u_unpack(@wrapped_string).reverse.pack('U*')) end + + # Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that + # character. + # + # Example: + # 'こにちわ'.mb_chars.slice(2..3).to_s #=> "ちわ" + def slice(*args) + if args.size > 2 + raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" # Do as if we were native + elsif (args.size == 2 && !(args.first.is_a?(Numeric) || args.first.is_a?(Regexp))) + raise TypeError, "cannot convert #{args.first.class} into Integer" # Do as if we were native + elsif (args.size == 2 && !args[1].is_a?(Numeric)) + raise TypeError, "cannot convert #{args[1].class} into Integer" # Do as if we were native + elsif args[0].kind_of? Range + cps = self.class.u_unpack(@wrapped_string).slice(*args) + result = cps.nil? ? nil : cps.pack('U*') + elsif args[0].kind_of? Regexp + result = @wrapped_string.slice(*args) + elsif args.size == 1 && args[0].kind_of?(Numeric) + character = self.class.u_unpack(@wrapped_string)[args[0]] + result = character.nil? ? nil : [character].pack('U') + else + result = self.class.u_unpack(@wrapped_string).slice(*args).pack('U*') + end + result.nil? ? nil : chars(result) + end + alias_method :[], :slice + + # Convert characters in the string to uppercase + # + # Example: + # 'Laurent, òu sont les tests?'.mb_chars.upcase.to_s #=> "LAURENT, ÒU SONT LES TESTS?" + def upcase + apply_mapping :uppercase_mapping + end + + # Convert characters in the string to lowercase + # + # Example: + # 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s #=> "věda a výzkum" + def downcase + apply_mapping :lowercase_mapping + end + + # Converts the first character to uppercase and the remainder to lowercase + # + # Example: + # 'über'.mb_chars.capitalize.to_s #=> "Über" + def capitalize + (slice(0) || '').upcase + (slice(1..-1) || '').downcase + end + + # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for + # passing strings to databases and validations. + # + # * str - The string to perform normalization on. + # * form - The form you want to normalize in. Should be one of the following: + # :c, :kc, :d, or :kd. Default is + # ActiveSupport::Multibyte.default_normalization_form + def normalize(form=ActiveSupport::Multibyte.default_normalization_form) + # See http://www.unicode.org/reports/tr15, Table 1 + codepoints = self.class.u_unpack(@wrapped_string) + chars(case form + when :d + self.class.reorder_characters(self.class.decompose_codepoints(:canonical, codepoints)) + when :c + self.class.compose_codepoints(self.class.reorder_characters(self.class.decompose_codepoints(:canonical, codepoints))) + when :kd + self.class.reorder_characters(self.class.decompose_codepoints(:compatability, codepoints)) + when :kc + self.class.compose_codepoints(self.class.reorder_characters(self.class.decompose_codepoints(:compatability, codepoints))) + else + raise ArgumentError, "#{form} is not a valid normalization variant", caller + end.pack('U*')) + end + + # Performs canonical decomposition on all the characters. + # + # Example: + # 'é'.length #=> 2 + # 'é'.mb_chars.decompose.to_s.length #=> 3 + def decompose + chars(self.class.decompose_codepoints(:canonical, self.class.u_unpack(@wrapped_string)).pack('U*')) + end + + # Performs composition on all the characters. + # + # Example: + # 'é'.length #=> 3 + # 'é'.mb_chars.compose.to_s.length #=> 2 + def compose + chars(self.class.compose_codepoints(self.class.u_unpack(@wrapped_string)).pack('U*')) + end + + # Returns the number of grapheme clusters in the string. + # + # Example: + # 'क्षि'.mb_chars.length #=> 4 + # 'क्षि'.mb_chars.g_length #=> 3 + def g_length + self.class.g_unpack(@wrapped_string).length + end + + def tidy_bytes + chars(self.class.tidy_bytes(@wrapped_string)) + end + + %w(lstrip rstrip strip reverse upcase downcase slice tidy_bytes capitalize).each do |method| + define_method("#{method}!") do |*args| + unless args.nil? + @wrapped_string = send(method, *args).to_s + else + @wrapped_string = send(method).to_s + end + self + end + end + + class << self + + # Unpack the string at codepoints boundaries + def u_unpack(str) + begin + str.unpack 'U*' + rescue ArgumentError + raise EncodingError.new('malformed UTF-8 character') + end + end + + # Detect whether the codepoint is in a certain character class. Primarily used by the + # grapheme cluster support. + def in_char_class?(codepoint, classes) + classes.detect { |c| UCD.boundary[c] === codepoint } ? true : false + end + + # Unpack the string at grapheme boundaries + def g_unpack(str) + codepoints = u_unpack(str) + unpacked = [] + pos = 0 + marker = 0 + eoc = codepoints.length + while(pos < eoc) + pos += 1 + previous = codepoints[pos-1] + current = codepoints[pos] + if ( + # CR X LF + one = ( previous == UCD.boundary[:cr] and current == UCD.boundary[:lf] ) or + # L X (L|V|LV|LVT) + two = ( UCD.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or + # (LV|V) X (V|T) + three = ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or + # (LVT|T) X (T) + four = ( in_char_class?(previous, [:lvt,:t]) and UCD.boundary[:t] === current ) or + # X Extend + five = (UCD.boundary[:extend] === current) + ) + else + unpacked << codepoints[marker..pos-1] + marker = pos + end + end + unpacked + end + + # Reverse operation of g_unpack + def g_pack(unpacked) + (unpacked.flatten).pack('U*') + end + + # Generates a padding string of a certain size. + def padding(padsize, padstr=' ') + if padsize != 0 + new(padstr * ((padsize / u_unpack(padstr).size) + 1)).slice(0, padsize) + else + '' + end + end + + # Re-order codepoints so the string becomes canonical + def reorder_characters(codepoints) + length = codepoints.length- 1 + pos = 0 + while pos < length do + cp1, cp2 = UCD.codepoints[codepoints[pos]], UCD.codepoints[codepoints[pos+1]] + if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0) + codepoints[pos..pos+1] = cp2.code, cp1.code + pos += (pos > 0 ? -1 : 1) + else + pos += 1 + end + end + codepoints + end + + # Decompose composed characters to the decomposed form + def decompose_codepoints(type, codepoints) + codepoints.inject([]) do |decomposed, cp| + # if it's a hangul syllable starter character + if HANGUL_SBASE <= cp and cp < HANGUL_SLAST + sindex = cp - HANGUL_SBASE + ncp = [] # new codepoints + ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT + ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT + tindex = sindex % HANGUL_TCOUNT + ncp << (HANGUL_TBASE + tindex) unless tindex == 0 + decomposed.concat ncp + # if the codepoint is decomposable in with the current decomposition type + elsif (ncp = UCD.codepoints[cp].decomp_mapping) and (!UCD.codepoints[cp].decomp_type || type == :compatability) + decomposed.concat decompose_codepoints(type, ncp.dup) + else + decomposed << cp + end + end + end + + # Compose decomposed characters to the composed form + def compose_codepoints(codepoints) + pos = 0 + eoa = codepoints.length - 1 + starter_pos = 0 + starter_char = codepoints[0] + previous_combining_class = -1 + while pos < eoa + pos += 1 + lindex = starter_char - HANGUL_LBASE + # -- Hangul + if 0 <= lindex and lindex < HANGUL_LCOUNT + vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1 + if 0 <= vindex and vindex < HANGUL_VCOUNT + tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1 + if 0 <= tindex and tindex < HANGUL_TCOUNT + j = starter_pos + 2 + eoa -= 2 + else + tindex = 0 + j = starter_pos + 1 + eoa -= 1 + end + codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE + end + starter_pos += 1 + starter_char = codepoints[starter_pos] + # -- Other characters + else + current_char = codepoints[pos] + current = UCD.codepoints[current_char] + if current.combining_class > previous_combining_class + if ref = UCD.composition_map[starter_char] + composition = ref[current_char] + else + composition = nil + end + unless composition.nil? + codepoints[starter_pos] = composition + starter_char = composition + codepoints.delete_at pos + eoa -= 1 + pos -= 1 + previous_combining_class = -1 + else + previous_combining_class = current.combining_class + end + else + previous_combining_class = current.combining_class + end + if current.combining_class == 0 + starter_pos = pos + starter_char = codepoints[pos] + end + end + end + codepoints + end + + # Replaces all the non-UTF-8 bytes by their iso-8859-1 or cp1252 equivalent resulting in a valid UTF-8 string + def tidy_bytes(str) + str.split(//u).map do |c| + if !UTF8_PAT.match(c) + n = c.unpack('C')[0] + n < 128 ? n.chr : + n < 160 ? [UCD.cp1252[n] || n].pack('U') : + n < 192 ? "\xC2" + n.chr : "\xC3" + (n-64).chr + else + c + end + end.join + end + end + + protected + + # Translate a byte offset in the wrapped string to a character offset by looking for the character boundary + def translate_offset(byte_offset) + return nil if byte_offset.nil? + return 0 if @wrapped_string == '' + chunk = @wrapped_string[0..byte_offset] + begin + begin + chunk.unpack('U*').length - 1 + rescue ArgumentError => e + chunk = @wrapped_string[0..(byte_offset+=1)] + # Stop retrying at the end of the string + raise e unless byte_offset < chunk.length + # We damaged a character, retry + retry + end + # Catch the ArgumentError so we can throw our own + rescue ArgumentError + raise EncodingError, 'malformed UTF-8 character' + end + end + + # Justifies a string in a certain way. Valid values for way are :right, :left and + # :center. + def justify(integer, way, padstr=' ') + raise ArgumentError, "zero width padding" if padstr.length == 0 + padsize = integer - size + padsize = padsize > 0 ? padsize : 0 + case way + when :right + result = @wrapped_string.dup.insert(0, self.class.padding(padsize, padstr)) + when :left + result = @wrapped_string.dup.insert(-1, self.class.padding(padsize, padstr)) + when :center + lpad = self.class.padding((padsize / 2.0).floor, padstr) + rpad = self.class.padding((padsize / 2.0).ceil, padstr) + result = @wrapped_string.dup.insert(0, lpad).insert(-1, rpad) + end + chars(result) + end + + # Map codepoints to one of it's attributes. + def apply_mapping(mapping) + chars(self.class.u_unpack(@wrapped_string).map do |codepoint| + cp = UCD.codepoints[codepoint] + if cp and (ncp = cp.send(mapping)) and ncp > 0 + ncp + else + codepoint + end + end.pack('U*')) + end + + # Creates a new instance + def chars(str) + self.class.new(str) + end + end end -end - -# When we can load the utf8proc library, override normalization with the faster methods -begin - require 'utf8proc_native' - require 'active_support/multibyte/handlers/utf8_handler_proc' - ActiveSupport::Multibyte::Chars.handler = ActiveSupport::Multibyte::Handlers::UTF8HandlerProc -rescue LoadError - ActiveSupport::Multibyte::Chars.handler = ActiveSupport::Multibyte::Handlers::UTF8Handler -end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/exceptions.rb b/activesupport/lib/active_support/multibyte/exceptions.rb new file mode 100644 index 0000000..af760cc --- /dev/null +++ b/activesupport/lib/active_support/multibyte/exceptions.rb @@ -0,0 +1,7 @@ +# encoding: utf-8 + +module ActiveSupport #:nodoc: + module Multibyte #:nodoc: + class EncodingError < StandardError; end + end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/generators/generate_tables.rb b/activesupport/lib/active_support/multibyte/generators/generate_tables.rb deleted file mode 100755 index 7f80758..0000000 --- a/activesupport/lib/active_support/multibyte/generators/generate_tables.rb +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env ruby -begin - require File.dirname(__FILE__) + '/../../../active_support' -rescue IOError -end -require 'open-uri' -require 'tmpdir' - -module ActiveSupport::Multibyte::Handlers #:nodoc: - class UnicodeDatabase #:nodoc: - def self.load - [Hash.new(Codepoint.new),[],{},{}] - end - end - - class UnicodeTableGenerator #:nodoc: - BASE_URI = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd/" - SOURCES = { - :codepoints => BASE_URI + 'UnicodeData.txt', - :composition_exclusion => BASE_URI + 'CompositionExclusions.txt', - :grapheme_break_property => BASE_URI + 'auxiliary/GraphemeBreakProperty.txt', - :cp1252 => 'http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' - } - - def initialize - @ucd = UnicodeDatabase.new - - default = Codepoint.new - default.combining_class = 0 - default.uppercase_mapping = 0 - default.lowercase_mapping = 0 - @ucd.codepoints = Hash.new(default) - - @ucd.composition_exclusion = [] - @ucd.composition_map = {} - @ucd.boundary = {} - @ucd.cp1252 = {} - end - - def parse_codepoints(line) - codepoint = Codepoint.new - raise "Could not parse input." unless line =~ /^ - ([0-9A-F]+); # code - ([^;]+); # name - ([A-Z]+); # general category - ([0-9]+); # canonical combining class - ([A-Z]+); # bidi class - (<([A-Z]*)>)? # decomposition type - ((\ ?[0-9A-F]+)*); # decompomposition mapping - ([0-9]*); # decimal digit - ([0-9]*); # digit - ([^;]*); # numeric - ([YN]*); # bidi mirrored - ([^;]*); # unicode 1.0 name - ([^;]*); # iso comment - ([0-9A-F]*); # simple uppercase mapping - ([0-9A-F]*); # simple lowercase mapping - ([0-9A-F]*)$/ix # simple titlecase mapping - codepoint.code = $1.hex - #codepoint.name = $2 - #codepoint.category = $3 - codepoint.combining_class = Integer($4) - #codepoint.bidi_class = $5 - codepoint.decomp_type = $7 - codepoint.decomp_mapping = ($8=='') ? nil : $8.split.collect { |element| element.hex } - #codepoint.bidi_mirrored = ($13=='Y') ? true : false - codepoint.uppercase_mapping = ($16=='') ? 0 : $16.hex - codepoint.lowercase_mapping = ($17=='') ? 0 : $17.hex - #codepoint.titlecase_mapping = ($18=='') ? nil : $18.hex - @ucd.codepoints[codepoint.code] = codepoint - end - - def parse_grapheme_break_property(line) - if line =~ /^([0-9A-F\.]+)\s*;\s*([\w]+)\s*#/ - type = $2.downcase.intern - @ucd.boundary[type] ||= [] - if $1.include? '..' - parts = $1.split '..' - @ucd.boundary[type] << (parts[0].hex..parts[1].hex) - else - @ucd.boundary[type] << $1.hex - end - end - end - - def parse_composition_exclusion(line) - if line =~ /^([0-9A-F]+)/i - @ucd.composition_exclusion << $1.hex - end - end - - def parse_cp1252(line) - if line =~ /^([0-9A-Fx]+)\s([0-9A-Fx]+)/i - @ucd.cp1252[$1.hex] = $2.hex - end - end - - def create_composition_map - @ucd.codepoints.each do |_, cp| - if !cp.nil? and cp.combining_class == 0 and cp.decomp_type.nil? and !cp.decomp_mapping.nil? and cp.decomp_mapping.length == 2 and @ucd[cp.decomp_mapping[0]].combining_class == 0 and !@ucd.composition_exclusion.include?(cp.code) - @ucd.composition_map[cp.decomp_mapping[0]] ||= {} - @ucd.composition_map[cp.decomp_mapping[0]][cp.decomp_mapping[1]] = cp.code - end - end - end - - def normalize_boundary_map - @ucd.boundary.each do |k,v| - if [:lf, :cr].include? k - @ucd.boundary[k] = v[0] - end - end - end - - def parse - SOURCES.each do |type, url| - filename = File.join(Dir.tmpdir, "#{url.split('/').last}") - unless File.exist?(filename) - $stderr.puts "Downloading #{url.split('/').last}" - File.open(filename, 'wb') do |target| - open(url) do |source| - source.each_line { |line| target.write line } - end - end - end - File.open(filename) do |file| - file.each_line { |line| send "parse_#{type}".intern, line } - end - end - create_composition_map - normalize_boundary_map - end - - def dump_to(filename) - File.open(filename, 'wb') do |f| - f.write Marshal.dump([@ucd.codepoints, @ucd.composition_exclusion, @ucd.composition_map, @ucd.boundary, @ucd.cp1252]) - end - end - end -end - -if __FILE__ == $0 - filename = ActiveSupport::Multibyte::Handlers::UnicodeDatabase.filename - generator = ActiveSupport::Multibyte::Handlers::UnicodeTableGenerator.new - generator.parse - print "Writing to: #{filename}" - generator.dump_to filename - puts " (#{File.size(filename)} bytes)" -end diff --git a/activesupport/lib/active_support/multibyte/handlers/passthru_handler.rb b/activesupport/lib/active_support/multibyte/handlers/passthru_handler.rb deleted file mode 100644 index 916215c..0000000 --- a/activesupport/lib/active_support/multibyte/handlers/passthru_handler.rb +++ /dev/null @@ -1,9 +0,0 @@ -# Chars uses this handler when $KCODE is not set to 'UTF8'. Because this handler doesn't define any methods all call -# will be forwarded to String. -class ActiveSupport::Multibyte::Handlers::PassthruHandler #:nodoc: - - # Return the original byteoffset - def self.translate_offset(string, byte_offset) #:nodoc: - byte_offset - end -end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb b/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb deleted file mode 100644 index aa9c16f..0000000 --- a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb +++ /dev/null @@ -1,564 +0,0 @@ -# Contains all the handlers and helper classes -module ActiveSupport::Multibyte::Handlers #:nodoc: - class EncodingError < ArgumentError #:nodoc: - end - - class Codepoint #:nodoc: - attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping - end - - class UnicodeDatabase #:nodoc: - attr_writer :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252 - - # self-expiring methods that lazily load the Unicode database and then return the value. - [:codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252].each do |attr_name| - class_eval(<<-EOS, __FILE__, __LINE__) - def #{attr_name} - load - @#{attr_name} - end - EOS - end - - # Shortcut to ucd.codepoints[] - def [](index); codepoints[index]; end - - # Returns the directory in which the data files are stored - def self.dirname - File.dirname(__FILE__) + '/../../values/' - end - - # Returns the filename for the data file for this version - def self.filename - File.expand_path File.join(dirname, "unicode_tables.dat") - end - - # Loads the unicode database and returns all the internal objects of UnicodeDatabase - # Once the values have been loaded, define attr_reader methods for the instance variables. - def load - begin - @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read } - rescue Exception => e - raise IOError.new("Couldn't load the unicode tables for UTF8Handler (#{e.message}), handler is unusable") - end - @codepoints ||= Hash.new(Codepoint.new) - @composition_exclusion ||= [] - @composition_map ||= {} - @boundary ||= {} - @cp1252 ||= {} - - # Redefine the === method so we can write shorter rules for grapheme cluster breaks - @boundary.each do |k,_| - @boundary[k].instance_eval do - def ===(other) - detect { |i| i === other } ? true : false - end - end if @boundary[k].kind_of?(Array) - end - - # define attr_reader methods for the instance variables - class << self - attr_reader :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252 - end - end - end - - # UTF8Handler implements Unicode aware operations for strings, these operations will be used by the Chars - # proxy when $KCODE is set to 'UTF8'. - class UTF8Handler - # Hangul character boundaries and properties - HANGUL_SBASE = 0xAC00 - HANGUL_LBASE = 0x1100 - HANGUL_VBASE = 0x1161 - HANGUL_TBASE = 0x11A7 - HANGUL_LCOUNT = 19 - HANGUL_VCOUNT = 21 - HANGUL_TCOUNT = 28 - HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT - HANGUL_SCOUNT = 11172 - HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT - HANGUL_JAMO_FIRST = 0x1100 - HANGUL_JAMO_LAST = 0x11FF - - # All the unicode whitespace - UNICODE_WHITESPACE = [ - (0x0009..0x000D).to_a, # White_Space # Cc [5] .. - 0x0020, # White_Space # Zs SPACE - 0x0085, # White_Space # Cc - 0x00A0, # White_Space # Zs NO-BREAK SPACE - 0x1680, # White_Space # Zs OGHAM SPACE MARK - 0x180E, # White_Space # Zs MONGOLIAN VOWEL SEPARATOR - (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE - 0x2028, # White_Space # Zl LINE SEPARATOR - 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR - 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE - 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE - 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE - ].flatten.freeze - - # BOM (byte order mark) can also be seen as whitespace, it's a non-rendering character used to distinguish - # between little and big endian. This is not an issue in utf-8, so it must be ignored. - UNICODE_LEADERS_AND_TRAILERS = UNICODE_WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM - - # Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site) - UTF8_PAT = /\A(?: - [\x00-\x7f] | - [\xc2-\xdf] [\x80-\xbf] | - \xe0 [\xa0-\xbf] [\x80-\xbf] | - [\xe1-\xef] [\x80-\xbf] [\x80-\xbf] | - \xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] | - [\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] | - \xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf] - )*\z/xn - - # Returns a regular expression pattern that matches the passed Unicode codepoints - def self.codepoints_to_pattern(array_of_codepoints) #:nodoc: - array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|') - end - UNICODE_TRAILERS_PAT = /(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+\Z/ - UNICODE_LEADERS_PAT = /\A(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+/ - - class << self - - # /// - # /// BEGIN String method overrides - # /// - - # Inserts the passed string at specified codepoint offsets - def insert(str, offset, fragment) - str.replace( - u_unpack(str).insert( - offset, - u_unpack(fragment) - ).flatten.pack('U*') - ) - end - - # Returns the position of the passed argument in the string, counting in codepoints - def index(str, *args) - bidx = str.index(*args) - bidx ? (u_unpack(str.slice(0...bidx)).size) : nil - end - - # Works just like the indexed replace method on string, except instead of byte offsets you specify - # character offsets. - # - # Example: - # - # s = "Müller" - # s.chars[2] = "e" # Replace character with offset 2 - # s # => "Müeler" - # - # s = "Müller" - # s.chars[1, 2] = "ö" # Replace 2 characters at character offset 1 - # s # => "Möler" - def []=(str, *args) - replace_by = args.pop - # Indexed replace with regular expressions already works - return str[*args] = replace_by if args.first.is_a?(Regexp) - result = u_unpack(str) - if args[0].is_a?(Fixnum) - raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length - min = args[0] - max = args[1].nil? ? min : (min + args[1] - 1) - range = Range.new(min, max) - replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum) - elsif args.first.is_a?(Range) - raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length - range = args[0] - else - needle = args[0].to_s - min = index(str, needle) - max = min + length(needle) - 1 - range = Range.new(min, max) - end - result[range] = u_unpack(replace_by) - str.replace(result.pack('U*')) - end - - # Works just like String#rjust, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".chars.rjust(8).to_s - # # => " ¾ cup" - # - # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace - # # => "   ¾ cup" - def rjust(str, integer, padstr=' ') - justify(str, integer, :right, padstr) - end - - # Works just like String#ljust, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".chars.rjust(8).to_s - # # => "¾ cup " - # - # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace - # # => "¾ cup   " - def ljust(str, integer, padstr=' ') - justify(str, integer, :left, padstr) - end - - # Works just like String#center, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".chars.center(8).to_s - # # => " ¾ cup " - # - # "¾ cup".chars.center(8, " ").to_s # Use non-breaking whitespace - # # => " ¾ cup  " - def center(str, integer, padstr=' ') - justify(str, integer, :center, padstr) - end - - # Does Unicode-aware rstrip - def rstrip(str) - str.gsub(UNICODE_TRAILERS_PAT, '') - end - - # Does Unicode-aware lstrip - def lstrip(str) - str.gsub(UNICODE_LEADERS_PAT, '') - end - - # Removed leading and trailing whitespace - def strip(str) - str.gsub(UNICODE_LEADERS_PAT, '').gsub(UNICODE_TRAILERS_PAT, '') - end - - # Returns the number of codepoints in the string - def size(str) - u_unpack(str).size - end - alias_method :length, :size - - # Reverses codepoints in the string. - def reverse(str) - u_unpack(str).reverse.pack('U*') - end - - # Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that - # character. - def slice(str, *args) - if args.size > 2 - raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" # Do as if we were native - elsif (args.size == 2 && !(args.first.is_a?(Numeric) || args.first.is_a?(Regexp))) - raise TypeError, "cannot convert #{args.first.class} into Integer" # Do as if we were native - elsif (args.size == 2 && !args[1].is_a?(Numeric)) - raise TypeError, "cannot convert #{args[1].class} into Integer" # Do as if we were native - elsif args[0].kind_of? Range - cps = u_unpack(str).slice(*args) - cps.nil? ? nil : cps.pack('U*') - elsif args[0].kind_of? Regexp - str.slice(*args) - elsif args.size == 1 && args[0].kind_of?(Numeric) - u_unpack(str)[args[0]] - else - u_unpack(str).slice(*args).pack('U*') - end - end - alias_method :[], :slice - - # Convert characters in the string to uppercase - def upcase(str); to_case :uppercase_mapping, str; end - - # Convert characters in the string to lowercase - def downcase(str); to_case :lowercase_mapping, str; end - - # Returns a copy of +str+ with the first character converted to uppercase and the remainder to lowercase - def capitalize(str) - upcase(slice(str, 0..0)) + downcase(slice(str, 1..-1) || '') - end - - # /// - # /// Extra String methods for unicode operations - # /// - - # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for - # passing strings to databases and validations. - # - # * str - The string to perform normalization on. - # * form - The form you want to normalize in. Should be one of the following: - # :c, :kc, :d, or :kd. Default is - # ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM. - def normalize(str, form=ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM) - # See http://www.unicode.org/reports/tr15, Table 1 - codepoints = u_unpack(str) - case form - when :d - reorder_characters(decompose_codepoints(:canonical, codepoints)) - when :c - compose_codepoints reorder_characters(decompose_codepoints(:canonical, codepoints)) - when :kd - reorder_characters(decompose_codepoints(:compatability, codepoints)) - when :kc - compose_codepoints reorder_characters(decompose_codepoints(:compatability, codepoints)) - else - raise ArgumentError, "#{form} is not a valid normalization variant", caller - end.pack('U*') - end - - # Perform decomposition on the characters in the string - def decompose(str) - decompose_codepoints(:canonical, u_unpack(str)).pack('U*') - end - - # Perform composition on the characters in the string - def compose(str) - compose_codepoints u_unpack(str).pack('U*') - end - - # /// - # /// BEGIN Helper methods for unicode operation - # /// - - # Used to translate an offset from bytes to characters, for instance one received from a regular expression match - def translate_offset(str, byte_offset) - return nil if byte_offset.nil? - return 0 if str == '' - chunk = str[0..byte_offset] - begin - begin - chunk.unpack('U*').length - 1 - rescue ArgumentError => e - chunk = str[0..(byte_offset+=1)] - # Stop retrying at the end of the string - raise e unless byte_offset < chunk.length - # We damaged a character, retry - retry - end - # Catch the ArgumentError so we can throw our own - rescue ArgumentError - raise EncodingError.new('malformed UTF-8 character') - end - end - - # Checks if the string is valid UTF8. - def consumes?(str) - # Unpack is a little bit faster than regular expressions - begin - str.unpack('U*') - true - rescue ArgumentError - false - end - end - - # Returns the number of grapheme clusters in the string. This method is very likely to be moved or renamed - # in future versions. - def g_length(str) - g_unpack(str).length - end - - # Replaces all the non-utf-8 bytes by their iso-8859-1 or cp1252 equivalent resulting in a valid utf-8 string - def tidy_bytes(str) - str.split(//u).map do |c| - if !UTF8_PAT.match(c) - n = c.unpack('C')[0] - n < 128 ? n.chr : - n < 160 ? [UCD.cp1252[n] || n].pack('U') : - n < 192 ? "\xC2" + n.chr : "\xC3" + (n-64).chr - else - c - end - end.join - end - - protected - - # Detect whether the codepoint is in a certain character class. Primarily used by the - # grapheme cluster support. - def in_char_class?(codepoint, classes) - classes.detect { |c| UCD.boundary[c] === codepoint } ? true : false - end - - # Unpack the string at codepoints boundaries - def u_unpack(str) - begin - str.unpack 'U*' - rescue ArgumentError - raise EncodingError.new('malformed UTF-8 character') - end - end - - # Unpack the string at grapheme boundaries instead of codepoint boundaries - def g_unpack(str) - codepoints = u_unpack(str) - unpacked = [] - pos = 0 - marker = 0 - eoc = codepoints.length - while(pos < eoc) - pos += 1 - previous = codepoints[pos-1] - current = codepoints[pos] - if ( - # CR X LF - one = ( previous == UCD.boundary[:cr] and current == UCD.boundary[:lf] ) or - # L X (L|V|LV|LVT) - two = ( UCD.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or - # (LV|V) X (V|T) - three = ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or - # (LVT|T) X (T) - four = ( in_char_class?(previous, [:lvt,:t]) and UCD.boundary[:t] === current ) or - # X Extend - five = (UCD.boundary[:extend] === current) - ) - else - unpacked << codepoints[marker..pos-1] - marker = pos - end - end - unpacked - end - - # Reverse operation of g_unpack - def g_pack(unpacked) - unpacked.flatten - end - - # Justifies a string in a certain way. Valid values for way are :right, :left and - # :center. Is primarily used as a helper method by rjust, ljust and center. - def justify(str, integer, way, padstr=' ') - raise ArgumentError, "zero width padding" if padstr.length == 0 - padsize = integer - size(str) - padsize = padsize > 0 ? padsize : 0 - case way - when :right - str.dup.insert(0, padding(padsize, padstr)) - when :left - str.dup.insert(-1, padding(padsize, padstr)) - when :center - lpad = padding((padsize / 2.0).floor, padstr) - rpad = padding((padsize / 2.0).ceil, padstr) - str.dup.insert(0, lpad).insert(-1, rpad) - end - end - - # Generates a padding string of a certain size. - def padding(padsize, padstr=' ') - if padsize != 0 - slice(padstr * ((padsize / size(padstr)) + 1), 0, padsize) - else - '' - end - end - - # Convert characters to a different case - def to_case(way, str) - u_unpack(str).map do |codepoint| - cp = UCD[codepoint] - unless cp.nil? - ncp = cp.send(way) - ncp > 0 ? ncp : codepoint - else - codepoint - end - end.pack('U*') - end - - # Re-order codepoints so the string becomes canonical - def reorder_characters(codepoints) - length = codepoints.length- 1 - pos = 0 - while pos < length do - cp1, cp2 = UCD[codepoints[pos]], UCD[codepoints[pos+1]] - if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0) - codepoints[pos..pos+1] = cp2.code, cp1.code - pos += (pos > 0 ? -1 : 1) - else - pos += 1 - end - end - codepoints - end - - # Decompose composed characters to the decomposed form - def decompose_codepoints(type, codepoints) - codepoints.inject([]) do |decomposed, cp| - # if it's a hangul syllable starter character - if HANGUL_SBASE <= cp and cp < HANGUL_SLAST - sindex = cp - HANGUL_SBASE - ncp = [] # new codepoints - ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT - ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT - tindex = sindex % HANGUL_TCOUNT - ncp << (HANGUL_TBASE + tindex) unless tindex == 0 - decomposed.concat ncp - # if the codepoint is decomposable in with the current decomposition type - elsif (ncp = UCD[cp].decomp_mapping) and (!UCD[cp].decomp_type || type == :compatability) - decomposed.concat decompose_codepoints(type, ncp.dup) - else - decomposed << cp - end - end - end - - # Compose decomposed characters to the composed form - def compose_codepoints(codepoints) - pos = 0 - eoa = codepoints.length - 1 - starter_pos = 0 - starter_char = codepoints[0] - previous_combining_class = -1 - while pos < eoa - pos += 1 - lindex = starter_char - HANGUL_LBASE - # -- Hangul - if 0 <= lindex and lindex < HANGUL_LCOUNT - vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1 - if 0 <= vindex and vindex < HANGUL_VCOUNT - tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1 - if 0 <= tindex and tindex < HANGUL_TCOUNT - j = starter_pos + 2 - eoa -= 2 - else - tindex = 0 - j = starter_pos + 1 - eoa -= 1 - end - codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE - end - starter_pos += 1 - starter_char = codepoints[starter_pos] - # -- Other characters - else - current_char = codepoints[pos] - current = UCD[current_char] - if current.combining_class > previous_combining_class - if ref = UCD.composition_map[starter_char] - composition = ref[current_char] - else - composition = nil - end - unless composition.nil? - codepoints[starter_pos] = composition - starter_char = composition - codepoints.delete_at pos - eoa -= 1 - pos -= 1 - previous_combining_class = -1 - else - previous_combining_class = current.combining_class - end - else - previous_combining_class = current.combining_class - end - if current.combining_class == 0 - starter_pos = pos - starter_char = codepoints[pos] - end - end - end - codepoints - end - - # UniCode Database - UCD = UnicodeDatabase.new - end - end -end diff --git a/activesupport/lib/active_support/multibyte/handlers/utf8_handler_proc.rb b/activesupport/lib/active_support/multibyte/handlers/utf8_handler_proc.rb deleted file mode 100644 index f10eecc..0000000 --- a/activesupport/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +++ /dev/null @@ -1,43 +0,0 @@ -# Methods in this handler call functions in the utf8proc ruby extension. These are significantly faster than the -# pure ruby versions. Chars automatically uses this handler when it can load the utf8proc extension. For -# documentation on handler methods see UTF8Handler. -class ActiveSupport::Multibyte::Handlers::UTF8HandlerProc < ActiveSupport::Multibyte::Handlers::UTF8Handler #:nodoc: - class << self - def normalize(str, form=ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM) #:nodoc: - codepoints = str.unpack('U*') - case form - when :d - utf8map(str, :stable) - when :c - utf8map(str, :stable, :compose) - when :kd - utf8map(str, :stable, :compat) - when :kc - utf8map(str, :stable, :compose, :compat) - else - raise ArgumentError, "#{form} is not a valid normalization variant", caller - end - end - - def decompose(str) #:nodoc: - utf8map(str, :stable) - end - - def downcase(str) #:nodoc:c - utf8map(str, :casefold) - end - - protected - - def utf8map(str, *option_array) #:nodoc: - options = 0 - option_array.each do |option| - flag = Utf8Proc::Options[option] - raise ArgumentError, "Unknown argument given to utf8map." unless - flag - options |= flag - end - return Utf8Proc::utf8map(str, options) - end - end -end diff --git a/activesupport/lib/active_support/multibyte/unicode_database.rb b/activesupport/lib/active_support/multibyte/unicode_database.rb new file mode 100644 index 0000000..3b8cf8f --- /dev/null +++ b/activesupport/lib/active_support/multibyte/unicode_database.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 + +module ActiveSupport #:nodoc: + module Multibyte #:nodoc: + # Holds data about a codepoint in the Unicode database + class Codepoint + attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping + end + + # Holds static data from the Unicode database + class UnicodeDatabase + ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252 + + attr_writer(*ATTRIBUTES) + + def initialize + @codepoints = Hash.new(Codepoint.new) + @composition_exclusion = [] + @composition_map = {} + @boundary = {} + @cp1252 = {} + end + + # Lazy load the Unicode database so it's only loaded when it's actually used + ATTRIBUTES.each do |attr_name| + class_eval(<<-EOS, __FILE__, __LINE__) + def #{attr_name} + load + @#{attr_name} + end + EOS + end + + # Loads the Unicode database and returns all the internal objects of UnicodeDatabase. + def load + begin + @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read } + rescue Exception => e + raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable") + end + + # Redefine the === method so we can write shorter rules for grapheme cluster breaks + @boundary.each do |k,_| + @boundary[k].instance_eval do + def ===(other) + detect { |i| i === other } ? true : false + end + end if @boundary[k].kind_of?(Array) + end + + # define attr_reader methods for the instance variables + class << self + attr_reader(*ATTRIBUTES) + end + end + + # Returns the directory in which the data files are stored + def self.dirname + File.dirname(__FILE__) + '/../values/' + end + + # Returns the filename for the data file for this version + def self.filename + File.expand_path File.join(dirname, "unicode_tables.dat") + end + end + + # UniCode Database + UCD = UnicodeDatabase.new + end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/values/unicode_tables.dat b/activesupport/lib/active_support/values/unicode_tables.dat index 35edb148c3de0f3815f5b847e014ba91a30449e6..74b333d41685a1e0a152ea1517ebb73f73e3ed75 100644 GIT binary patch literal 710734 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

)FG4c2hmOv1d=!vnPA@Q9b+EZR<=_))UP- zctK{y!p!^e`N?FJc``HiP?>u$b8nToH#1)^Gh?yL%VcIO?unjRnP>Pi_q5F2Rp#!@ z+)HKd#ms$G=Dyx-+lRNUGfDNH#NMyT-dNcC)QYe(MfIM--aS?Cp6uO6_3p#o2W4+8 z*857?8;g6QS61(tzTUm8cMsLO2YdHcy?e8FKh?V*Z|lh_^JHdzU1r9@%x`oEJ5yEW zsm$CV|TnfV5p z8H;6JDKlenPxQ^oJja*0uVwD7GWTZYekyZ6W*(?A4@747bLRoxZ5>v^(sB9>Cs*Wp6CjdzI{s#XZq4tM^=A?|#<1kLulrz5A=){n>kv z>OBa(k$RfSJdK&(l9{nE^JrwAp)${4=6))3KV}}NG7n_tBQi4<%e-1<#^RpnpOtx@ zFLQs(&{t*d%gh5*<^jw+SY;mU-PVJ=+j_d{J)OPZmc6mC_W<;ssd~?3@BXTHfA$`v zdJkgnqp~*^>%B(y#^RnBkkxy>ulE4!-B0!I$KC@~?}6++MD-rR+j@q|JcF6vk(ser z=HO!u@bj-(s`D&%9-ul8VCTWA^I COc!X&TD07EbfVcS)CX7IuEqY{Z;4w>^w+y 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 literal 656156 zcmaIfbATNA)`#(Q{ep>Yc5K_W?QFEWv*8A7+qP$!wQbwBZTsH$+g;U@dd|sx|G0mg zTW6-bK2KFo&m@^GTePUs{!#xi#o>fMq74Ikj##;+c#qYywrZ`%QvrHwr=^xjm7JCDK0ax z((sj9$$!d$b%w86y>i34jfKOD$`?mZEge|1@PBXFd*kZv`aEkl?CCyFU45Q)D~i|a zvo2e?cKPPb#bt^^kD|j z{f3d7Rxe+(JzFJYtK_mZN4DlRTlrL%^5$uVlbB6oK3nvkrKr}6)ijz<6qQG{@~&D% zRIBK!Wl=5bsx4qOjpiAI{;a0aZuDd|jbN44^s!a!EjXg7MZnntq`RY0{0u39BjtMva=tBPt>UA2~| z*3wq1n5tIMJj-w@t7(j1ATx)gUm&B3NK(-yse&X`T$0vE(%L0i%p@A^6CK1P8tq0O zCedg%q9PI^j#HI zL5M0YM0JFy?n1Ofh;}Z-GKSD-P9zLv2#t25KSO9V8&NfcsOCb{M2MO$L|cStYeQ5` zg{W#DyD~ylb|KDW2#xs=;f|hoPZw21iK?zd4V0+iO0-9b_O8TEETPeyNf^cw8tuja zme6Q6qUtD7-Ib_?617~3b|}%#mZ+90QO!Pf6_lvrN}RC{f#$Xpa)@ZHels64mWvS4D}c zuEg0ap)r1OTEQ>*gZXttqkW)SNKwnB=!g^@U5XVK&|l+SRH?)zU{bnI{^~p}NNSsjh)~R2!zXooOeScCw~X4ctC8 z?Cld)(p;l`q9bXp(QXXp<*(6fM72<*mb?7xB1Bymq9a0dv>|GyF8`YLv8y9Qbr<4X zhR_&?_?Tat>mWoO7osMhYdYvvgw|-DXc$Fkjdo)Qp*5O~s5YQ$JLr0VuIHdT0lJfg zu9bqWWgoi+pldkj^9ZdmhCT;Zd>F>p8IAUV>LNv5m!cL@)N(0SGlfR;2w^l+Xfzv9 zeL&WCkevb9*+SM%LDsgPyCxuOTF9slBG<8z!})~P7(+h`=%^kT>p8~SV65#JcP67o zb0T3388zCCVZ5R>nvJLdpc^>oE`aW0q3fie>)6j-3(&P3bX`E#bYnGYmC_s-U;8f)&pxj%NjLAmWDPl` zb6R0M*)`gYk!06sHloI0Z|vB+gT1?Dub*PCZ$Ecku-A3$4Zz;OUEd{y))+$%902J0 zfUfVL8v(kJgWiqM8qJA>353>YH%1X!quGd>0J@2T?g8i?7CL>7?hNYzx}Jk>2zlxJP&>GE&gh_009Y-B&S0U#SV$i{$dY$2m&h}_IZ4wn*IV;(xZ(w09*X$r}vPI4V3HJURC zlPRguZj7a*Mzaz1hGcIm**GQH*nVt7NH%nmO(5CCNj8UMb0>KjB{jyE?Bl#-n*p+! zgIrHYjpjtc6hdmW8{-J6(QHJ00NKYvHc3G?u^-zAkc}K)4-55_ujbmaWnq{bL>G9g<4vW0`(NJx$5M8Y&eYP1^@2&vI*MEwBS&q6j!K{m4=+XRqJ9AtAq zHg}LM0ol?)ZX=||7;-8hvw+Mx$lVF4(VR$_PDqV*Vk;4l4!R|vTRP}AfNtZUuO_s{82SW4X91mc(5(U8+Cgt2 zv_^BHVHTk^+KnlM)@U}OL4Y1)pXIq0^4ZtI}0A+*LA`X)lR z1awOW-3HKY9Q0N~YcwYsW)oVY*@y;%aj<18-TUR zfmJB(wPUjOAZzc)t|OVonCyCzwFX&hN7fEx?Ht*jB-3b4D$FIBM!PYcH@il&5e)_E zP>b3oh1$k`Y%5%)t=v`G7U*qr=tVj79kX`;dk4pUJ=rzJ?C+6%__owjj)rfuPr41V zv~gM5BTIXiWiMvYXdWTVV-}5eV+ONmG#k+{WEp0&v`w93Tl=xCk)^fE(hgbLDGUGR zUq^)K$Pk&gio*>op)oG;6HAOhi4m?uTa;+)N_0Sp4z9%BETPeyNtn+P8tukRme6Q6 zqTwhp+?HsUD$&k{g2wzD2}?;z|RXh zAV~+8q%)FqHc7rH4mUB0#yClh6?mLcNHWSLX^$lBU6M}e(~UaW6At?_iAKX27BY!O zyD^(dG@6ZQB$AA@Njju%jt=%?+aXCicXM<^iH@#B7nJB?O1xJbZe|IMaf!w(F&ZUC zyAmBxqJt~Z86`Tq68o`)Mk5gxv4lpuF^45InvG}_N{q54I;Ki=v>)3E(w&@iS4ej? z(jOFuTPUqDmR>^XF_0ePq&q^oqm%9e=`K!se@bgKXBrk$TBF^VOKFW}BN`3q(N?-s zO1hK%*bcbnJGg7UGfH%JCAy(RH(%mbme3fNxRE8sqQqENq7zDVawWQ=L|0eh0G7~b zB*GGw&}cX2v4lpm5sg8KF}6hKREf^^V>_ZmM^~Z?N_250x}!vQme9Xwy^SF>#vxu| zh;axp&V}fV5S?9!ZV1uMg*cEQG#ZGolp!?Qjrk0r(QHIx5n`+j(Ipk4i~ZQHfbQy` zdjPtJgT9^68e{0`EAjPqJfO!r=q`Zn;-I?&y1Rouh|n6%iH2o_)@U~t5L%G5^Uzl}-_&OhA+gE=pHK z>FT2NK$IRX%E64H(V&E#7)7JqSjZ?E%|E;L>HnPLUeN>dLl$m7vd0x&}bmSa)!`oHx@C3Mzax3K!^!8 zM4HM%>Dz!*rrb9L=9}Uk2+_lZ=$-!TQE&VC!(9xaF%Iz$zaC6Nh)FI)cZBHfLi9q2 zUM|F;4587SXjs7z8tuknhR|p>qKODG(T3=eqV8cowi`lpb0K;nL{Ar@4?^^DA?{`f zjd6%wc}Gk}h{-NQ4}|F9Li9$6-Y&#p4586Lgp~}T(QYhZ2#sbVnuHLOY>1wz5Iyb3 zc1MWrE<`Vc=%o<3Z>f8>$o+3eKZ)*(Fntv!_m3v@?}7Ypw+QzzlE!%ZP)3@9NK;&- zo`}@bMe2h{eO#o&8A+o-3ac1NquGciBf(^wpjRqEFZ;1Qkf4W4&>IPQ=MoeZ68x_W z{g9!byFczFy~ddS6Vguw{ZvQa3-rAleP7V`b@WG&UZcSYt4XiXY(!H)KgH7bPSN+a zAKMf3Jso`?(DxBNe~8*2%>9$AeZ;ICUG4XgTw|U*{Ak`TO@sL~XWkp;y`6bKnD=w$ zN77uQIjgWU%{7{hXe!L7TJt_B^FH=t`@*zu?sC>EN*}$V$k)G0L<3+vATb`jL*x5t ztTDc`G>h zW+R#o=INHXUy8Y({n-9s?k{G(It&8oAd%vDc#w=5W5z4VI1`LB9b-Q*_H&E_!8p({ z9z#Zr_K6mgQKQ+2W`J>qW$d3~>~BA|Z;jN^sBaB>d;pjSIOf4%9_*MOBD2Prx$8i@ zD9i%$EXUj*%>5nnATSSd%*T>hqdC#A8<{nljc6vAXIka~DaZl#WBY-*ADOEZM+3n; z&@m4I^AN}UFqt*R%*A}|oek#Mj(Gr>2RP=zU>@w4k0Y~20}X;uPv&NYD05Z=3^Bl)K5X=J|^AIo(am>e)S)+jn zYssw9Y(%rcJlir4N-+@(HxM^vE+kO4F=O-$21H~!yMCzWYTC(B&;WsMzayk1=C#1G$h3|#D45hFb$2bJpH@4 za$!f;-UwWKBiyz3I8immsB8JfYd%otJJcaS9pX@j19iAVJ&C9q&1r`XMAc|EqIp1_ zXHkcyP>0%&9R}24_S%a^f^no{e1eP`W5#K#@g86S7#BFkp97)O9{gkwCJj2g{} zhK*#@Xf~qxV4QCmhou;Y*^eC##^H`}6c|T2#wW?BF}WJaxDbpB9pf-C4s(nn!8p<} zoS#}7>C=B9RbD>j&U>?M?1!+$fz;T7%Fw=pPVd$<09uc z9FD`C<0v?ea*n6cQKLE2u!)Wu%|^5kjti~hh?L_9`>`Y8IMO+ef#VqG_%t0g#+T#A zyc`#Uaj|0@0mc!IaWoi5JI2$@a|$AWpRV}6Fr8e`@^cE*e65-=}u%p<`((lL(#^BBi`I+-<^6AfF)tkG;li^06u zGLK3@jE^Jp-ScFg0zJkBvcOJn8!KhGs&#cK!iQWtkG;lOToO@(7&myx%0}=KlvqrNKEd%p1%RDy4Jht>>caDFf{b(?c zcFg0zJWkB|K6P~Q=pB8pFcIVv9r+6+*BFx*@ycEf^5u?vEXc@o9sX!w638bx@)t?2F(&_n z-=3`i`3grq4&>t;`9zRUbmZrdTw^IpLcTZ2HJXiRImnk=^6@G1@ueTTYfL^CxW#}>!-<6u9|*-wQ1MA?HengZ`B?h=2Q%o=0n z)5*LF%&Q#p1Tar<%#*=9*)g9-W{u`V!oFnIXf~piU|wmNC#IMumVWGRG4psZk9W+I zz&yz@PX+VTbxU7Yu1cu#iT)8IYLd0$9xjiq9V_W|_QXf~##yr+~NTNisz zg7+lnJr&+lo%alQ&v2LZ&S2izF~3e`jWP3^qrki?n0Ix|Q@}jMF;55cbjN%VnKhO| zCCmqsS)dTf2nJQ>WB9rH9WPjk#O!8|j$tY`SkdKY-_;=JFWx5n7JK3}b; z!gH$goB_`n)-x(buVULPl+asasaWED5WO{;jcF7~au z#>`W}Jk>GJ0P_sTJR8ij#hiQZJj-9!#qch6-fz)cW9*%!_jGtqciyw$J6*i_t<+Hyr((uned+Jyyw7sj=cHadN(ld=9u3mv&NWt zDVb-0d4^-24d&U7c`caNI_68stkIlEIF!s9&Bn|W^UTs?n_}kaV4m)nXMuT^W1b7< zxyfZc$6wZK;JwCqze8`0vG*)`&xH3(=RF7BbDZ}&c&~Hbm(g2esaSGZA4YGDW@A>$ zdsgYO&9V0kc+YU&v*A74dC!CQJa<{I1@l_R{4SX_=9$C8z4+%_v*0|-InRajT<5$V z&g-4?<#g6qDwQ}NPG^l~V|L1UcImM#vGYtg&vedn;5^4U&xiB;-t(OI26%69-dE6DW2so;eFVKV+Kq$C;6Jaa(QM2~6`50d zY-?O(7K+SrMdqT&TvucPiY#zf{(6L1??SxK5E|nUfAIxo4noXvA?72*d>3LPLTq#) zwlRdpQm7=vkqn{HZXC=I8qLPsREW8y$M%Rr%tnaWF2p>9n5PhnDyIKY!~gn+4GR%y zVRFkX@VCqcl-l4*eZW#0<5GvS)LfLB>q;#^sRgdo?kKgpD|IDHX)KjYN*%>g8tuj* zETz$G%uAJ;S9)yExYQh!n&V2%N2&SlmRW=%i`*@<5g|6Z5Favx#yG^xUGW|3JcO9% zLM%jxg)YPB**yKyK(Xfzx1Qz7P;9@{GpF&81`x)2KxVu1^> z7$FuXx5grWYwV69ySpMEv53ax)?ktOC^Fv_S%e~sT#?Nvve^~6nng60iX}ykVG)gX z<1iM{Xf_t4iYzESws%})9*WF!MHZsSLRVx7iY#%r#wLW=~czxDwZ}gvL^-q{Oi-q0w#}&Jr5U#==yIg{8;#iA&5!iTSR?B9vI< zN-RZ*rOCaq#NQj6kz}(=@(Gh@jPH#TcyBC3k%g|v5)@hDifl!Zt**$mETXYgEGcpv zi)gePN3e)Sv#}^uWKrp{ed8hvP-KBCvKU1cyCTa_WSP4+wjjh77vfWf&=`kk&Jc?b zVv!566d{(n5PKlR9xlXn456_UDhY8sLuj-cM>2#)v#~f8VsYuQ{o)Wy0KLRP?*!Jd%|{4 zXZr?MbxNXg7|btwyu4EM>c_^w@#1?M|@W z$z7x?A-d9Cqi@m2mF-v^@mIMJ^usxcPbwi~`sEr;lGC%Ouv ztDNX96xC?XIGjpRjdtUBifS|)D^j8>%&}-CL{~b|oguojyEOL&wIN^+$+7VQG5U6N~WXMgSO2eSPf z*|#Lq7+-sD^V(Ypv6W72XNc|W#BQUQMsr5tbc$)T8z)jsquE%M5?f`CMY}?5S9fjg z52*be)OUo^7(+D}jGJ^7pjJ7kT>!OGYF;8Zk$9Yjb>wY3Tm}E78L`k zIJvZT^_SKG5Iew$eNQosu~>Eu#8yLWwG-PFV!JxAJ1C~noKZNFVjAtn$rRIQHg-( zcHwoH9=6t=2)~_i{xk-9o1xyuLI;d2YCn}4{?w`6H;Rg zxrtX?F(8W_BS<$o(g#SY(VTL)kfa*z#@Qs*Xg1a-q*Fz@-W-cIfOLZ+-2~E2?ruL4 zl1DnpKPag&maN>AlItP4-bwBb$=#jggOt>0&NN&^NsV^n97<|58ygbIX_DMvjzt?G zxlxk(;c6fKyTVGFw{Bd$X;7u&_y=gwW{_@9uF_5ZzCQ}KM>*R+X{#}|{mWdX8(_P^ z*=~aECTIH)Z8e&64<)qKXgAKKtwyu4F|nO4+l}T}v^#8fk8RiQz;+94x1?;%E5OmP zJ=)p+MO%$|+i2=qeDk*vv>P4mX3%bSv=5V3qdE0(F=;j0jq^yW(QNFV(9RI;?&esu z6=GZ64So!uj&V?b6G~%z5#BSHH~8+5+TBTQfz%c!^$4XjnllNPP)eiSIG<7)&Bmrg zYNn(%nPbr&klG`;wzm5F_E?Y|>&X5gna23qx}Vq9CWvivVp}1$)rmbyF^%So!le|` zXg4mPm`1a)IT4#BvCZaKv<0{AmiV^Sf3DrVB<=~?JyW#iwmlBC$2r=6NvkoYeU`MF zLA%+}?g8389PMMI)o4yVTt-@rcH=_QYBU>L6583K-C~YKTS2=urqw@!cC>qeb}x5- z9}m&vo#=lksxcPbg`!&^y2Xj^3DG^B=;IXCXwEoXPEn0^<06V`G#gtJ(K!;`YK}#F zKy;5-RDS~OME8d1-pR$fmwz2N0kkJL+W(SPV@z9b9lpkF1?^TxyBBEparB(!ryyN5Xz?FrgFV_N+r$I>A=5^pi(4OdM%lsK7Pbl|u zm7p=E9ZK3gK)Z*d-5a!fJK85ntI?c#*hX57cH?5wYBU>rCTB8FXR@a`7VQPvy<*xS zJD}YcwEMc(fs-J5k`v8PRAVfk$yZd~9(Cwe1Gxzx^pgYCU1=4AZ>GZRM ziru$=%e5cq_H%U4kWQmHwQx1*G}?{JNT<lFgw+mm8F@+*laJF?GLm4o!PTA(`e2qTthRBcH?rIX*3)ACT5Fdwy!xB?FX~{ zVzZGu5IYcJ2RgCSAa+8<*3$6{S}Aa)SM4sv3rL+o@XR-R%S^J1ad5Pny9Ajl4MWY3dKqdBE;9mzD> zjcp{;Xg2mw$d-s~e{(E40AvTmWLx; zVj9gEh3hG%(QaHxF^y*9fJAJm#11gWq5~mzU@W$I2V#dn><}k*CdAHkVnr0w7>jk& zPli%2{s%+sU?=t>#Wb2T3O7(pquscQVj9iHfr;2Mi5+N;MF&Cbpja&Tqr;-jTUTuV zDt0Km4s~8mb8`n@&quIz5zB1%R-Is<#AbLnF+Rup|4$;G%=s6HQ$B9;^sK!|IXb`Ou3eiJj(f&^K2#6lxM9+ojxlXhS zMK#8vk5lvzh#ulZ4~OXCPV`lZYBU<*7K&=L8`n`(quIz5zOdv)-B*^wAbMCVn)`Vo zUnh@*=#ftJJcyp>M5|I%V_r18IFxT*4h89cPV@qZUf@KlQ&eLt zsz2>be`z`#qK7-tqab>e6MciC8qN8J+bOEiZrn&wjbMsvd94w7oL8#j?uquIzD zk|sUG9F2|w=}|Fh?#G5CJr<tl4>+3 z9PT8kM!Rt{Ni~{{%%N%0L(S3XXpkNqljeSINYdj#dYmII0cnXNtwmCe@qPao@B5=5 zdXy7A7NW;G(YGn8(VTC%i=rCs#w`@pXf`s3r9}@jN26mPdQ2>u`*9*gkB8{-PV{1k zUhG6`Q&eLtI$$GSNsor;(N6R@h#u!e-=U~RbH3qjifXhQw^CH2*~lE87Cqb?jgE!r zv9W0UQ%0Je0Miqk=_N3|#F^Hism9o}8BLFY=`qgqc$gmVOy8xcMsvpD9-3;j8@JI^ zquIzDkv2WT9F2~H>2a}X?x&CxJrSZOI?+oZdZ`nwOHqxnXk&^V3(;ep=m`)#!HK>{ zQH|z&!@U&MXg6-Bs7AAqIWjGJq&XTL57Fae(cDidDS8q_PjaG{LG&^wT92X{W6?AC z&HZr@JM^TM-;|_{yG#iO@b5=*dp> za)@5;MC(&jV=Ow6*XZ#OJ>H3)1ksb6=m!+lXwEm>Pf?9_<4%fdG#ik|40jet;RRdCKjH&h~)d`?F!BL$Is*@enhosVIP9!`)DvfsIE>dYU8<}I$RL7X3 z(Mh=YPKqx+{nlr5JD&>CQ=RBGh;DPD4JoQI7TuGgCqnc@CwdA*PjR9jQB6Zb zS3&eDC)${z8uOx|O*wwAc``^(cBH3)^fX8M2}w1Y6AllPRHNOvm!ulaM&|f5>G9@h zbSg+sjY;=+q-TKi3`cr3NUwIJO-QOSzDURHj<@lrK=c$RdOAc;ccPzCRHHfH@CZdU z+Ku}ts?ls@PDqQMV2(zoLG-j(G+Llb$Gieu1G8(KSyP&6j4#8LBY7E~3ba!l+8IDQ z!=ZgfG>ztz!lOjfXgBUBnntscIWdiPqB$B}3yW)=MKfAxjIW>bc>SCPiqjm$nV>k+ zQG8Acjpm7l$4H^kZahE=jbCWmbSe@mpzMz#xJkv78;c;4Nv>Ol7N~77xoSeeQoNSIp=fFyTJ;_*I z53B2)RSQ~aj4!M9oA9!92B^+(RA+j7~ z&IQ%EqSE^f{g-%kfmLkje#OuYfV;uLWeKM-hU-JPGXZy|gF6Rs=Qy~p2&d7UR(O(d z8tulzgwtp?GN-2DPBllP^8j~VDO~O^!+E$H0e7Q=Ye_hbG2C>*odvkF9Nf8pJJ-Q| zO*oC_w8B$_(`YvyA)H3DkvT05cbYjGoe#M4d2{MN{(cjvZgNzuNTo4P6^h34h3srt zo$aj7gVlM?>Kj^VG-nc?rj z6HQ}$eI3N>>l~P!NZ&2=B(P$N@HwQXFRRWht>Jc>LOTO zQ*-N~77xoSn8h+Z>H9hSkN+>ULP&?yTC=N@IKr?xVk>nEFdy z7l7&lM^yr<5=ZqTsWh4s2``XJquqFlR2t1j=A1OuIp%0|QH#`JP4@UDpuEIU-T}%x z9AyVmYK$q5CFO;nywFiz49bfg} z^U{>(nWNFgpuE^oUIxm`9OYf0yvtE`BBjQd@-kkPC7>*El$V0?Qb+jU9QLoo)>wL~$?qk7h1eSH#&g8hXf`qzq%<=Zn4?h%uuD?dnFRY% zU|;I6uK@NH4*MQp-{Y{m5L@F8u`dDkB@X*?U|;UAUnQkRLlK@QrAD)nxiC$6p*b2| z49bgBlu<%?87MDvl-oeL%~9S9%6lDUS5j(>DaYxD{i)a6OF?<5qr3u?S2)VoNU70K zgcnGu(QIVWXOhv0B)_z|%K8l>H?3a2X8SiEmq7KBlxj#+FNf;oPW4KtUg=ctOFx(B zKBwA^sv2X}#Z?lk##;Z8Ql=FW)2m>5 zl{38-rq{a5^C3_^)(QITc zOIu!Mjz-&Hxh-W`lvrL3%d4H`b+EiHxjwJ;*XP4Peb}M)CaT65we?n@UJJ8po!L7y z(`e2)yhbyPW+QWX+U#<3G`bRISEkG=CT7>b>>6iwJjJ zKS;U`R@XVJcWI^3oNIWURvOJl=8Ck{73OGk6|AmGSyf7`u7%aL&guqO-H=>g*Zb@1 zQJ_8Q(E1WhV|;xL<@I$v%&vE4@6k-7Ip^>O%`}>g%(k@IHa(5}pTHG`9eyc=;MFO? z%8B505WLO_-Uz`P-PQIO;2v{u{RpQqzS>SPSKAGcyTQqoc@h5+OO3`QyiZ$=cH>Rj zYBU>}E7P`DnxoM*(7Yz4StZfD9-7xX&6}WkQ*u4t=e!TPvk?N3&X@%6Zo*W-;) zz0s*=sH)MNbNGO&8tukgRMluUGFPQlugX8s++Pl~zcuk%@LrqZt(x%O0NxuM@6F)7 z*yu!8(yWeGRioL+T$5J4#vF~VhwAky)#{1rO;Ekbsoo0JTirGK6fmE1n1hI^F}_AirtuoR z1)8@w&9cm7#mR%$JCaNGc7Mq}3*=`V@=zjc%p*tt z@Egh7VSKwYu0Ugr#wUD6V~uv>0~%{I8<`u@#y6Ow(ali3Ii*@VQN0stcS=ovJtOr~ z+~UG}?`isHV|u zWNu2U-IRZ#x!-PL-)7zlzFSj#brZh3!FRX2)?R?x3r=kW)imaxO!(Qn`rQS#yBu33 zvS~D@9KIx*M!WGb*)*Ds%*|=GoAb{!_bW^++ihUGEyY$ZVY>%x_as-{-Ttb35q>W^ zzmfFQ82kNX{O*R|-OjHv{WO|$4`0zwquuy~ej3e2=9aYIEqbQ;uO68le)YH=h_|N@ z>nDi!0`XpV?Y#uMmz>=w+G&jK8qVNX-g{tokF%>nJB{YN!`HOaXg5Bkokp{fxizti z&I^O|OQ3GeKiBA<9opRiyE{^L4HCQiV0T|~0p9B`z?XsevO^qAM2#_GFN1h55bt$} zRf(w40EBOdsL^hGMnsKfBXe8&0=&%}jqU{7ohi143ETZ(yWd@MuR!Y+r!|IJ8sm)3 z_QaRg`+#+y!>UFsjpkIsx5UzDH$EqpMzfK*J&kp{IU3ysth-WJjS{Q}fb~Ffjot6B zu~(t?s#6ckSkWQmH?eIP6G}?_XNvF|lWbRDU z-I;%)x!+=Ezr5Z9wR=)(O%k<-p!QI5LW6n#Ndd z0Kb8F2x<>GwOUluXwEqNNHvXi<7=vEG#i<_(`t8{qtSi9x-W&*EWvsNSdTcYH-Yu0 z!du>%uiR3+Vg2^MgL6Ol?oaVGPxu}M-=pHoegE}{zg6FY<6F*g5*;jt{``fs|v5#PKmWKISgNx54+ek(3;K?uJRQls7Yo{$>NM&|xBe7h3N+t*O+~7+-Z$^|zf;Ke2ioSdTlb`oz*`P9^+CERA;K z2V!Y78<_{vSP$rlRwy1@9F@^KyWCUFd=UQ?l^pwMo#P2HMjO?E|2F;Lv6eO=FDqF~2%I1+=FeS|g%qG$$PXB$`IM z@iWmhnvKlEX|#t6XrX}iag6p1NS<*dAA;mVM>3Nn8uKKf?OeXlKMj+ook?SwXf)>& z{-TLSyYUN6G@6afBWaUI3MRR~36sD3K8a19g~_wdguh9m(Qf=o5{+gf^Jtpn(E>@O0?DT_$#Woi&XIf!l8+t9Y?5eWoX`<1bPxyx>8tuk!G|^}_GWxxlWhxIUU!4DCzK@k2&3qPPJP(ZL9mXfX z_{3q%A%?~n<57e0959}97|n>GvGl1X|NiA)VraA*zY{~F*~mPe#&|q`fs8MXazDw* z-!q@bCNIF`1)1c&fqCA4HUAVipE{hm#L<|?iB9Cr^E_;xcQ(ywqtTpK_z!I~+KoSG zqtR?+o=Dp~kw52&srN!(#5OO&=Eamv?w2{_6qEl7>}Rm~%-PJNjmFsKYuda3n-`o- z3)*Nj=N0}-8;y43PugfS8<{85Hcu98O5f>x8QZ)Bo0r_Z^f^dAcO>&kqA@1vHUhFQ zg5*Uo)!(iAM7|GEb#Ro+^-(zK{7Txs_U^)}j|$;Im{tD~?`< z*~`iG^pd~Vz5w1A4sQYRG{$(t_W|BZzo@~fbG)zP&foknv?p)Bb%nvKkJDU-}|1-jB#pzo5~40JC#x>rE=3h8pMP_M)8 z^^~2t4ZnfiH_mPe?KH-AS1g2GC{vNI&K2#MN3TKmHK*H_x*CmLC`Vn5W+U@_TKD;a zZt08I_sN|K-Itv1tI&Pb>%IZqH>AtA5#Iv!TZg)os2X>Snjxx2`$(??^>v3@o@5%$ zX9#67441JRnHSQiFO+_K=7(7GWoW+aG+%?}YhLqBXuc`U+&kAd{C)l%Sif_u%gCxR z&l-J)SI7`iRb%NnC2s@Yfa)7oHTv%#DH2WQ<3k0iYqT2~s%tbGnHN(Jk$Ew1GOIW$ z{prDvG5#ySf5qXy4*b_W{#(F*D}`@fD82{&_YQw2;%kiYqmk*iG9eIOqdD>DP2j)j z@XP#}l8MUv89&VU% zETFdqZzI6l3c%NrAK?Cjb6-w(jd_r8^&-ANmnFPL`$%sA{w)We0emKb|3&{UWczne zp(9_#HJXPB6`4k(*~q+{hJU#LU;6gq=NSGqz`y3;-vs=d4*ng$zmr_~Z~K>>A5q{( zS6~GTXpAq($M%IxIR?;Z&O3S=0p4~2A_Rz%08gEOhv~!s8qLFmN(`XUY-CAz)A+t7zcQg0m?IgMswcLI|%TO z3lI<>Bmth_OHXG8&}beeRAvB;W+U@zI>4)i0HrVfzs3RHK!7(~fVUCgZ3f7_OMDLn z-ctd-_WTU^pB?-v!fTA-+wnEO0^v2<2YMIq?>hLhfG?ZCzli^sUg$!2jpkuO6~b#Y z8=2SA@UIo%OW#2L7Q?>@_%|K=JAi-3!@m#s_Z|E%fd9q8uO__4JbXB4F<QB(IbA8Q(L7A3N_mZTqe2GnLp7R>%Cwy|@on-plDzGbyoV(3xg;MV$%ihd^rXdWiiW*Uulqbk#AG#ijgI zX+CgiK1Q04U7F93<};V(Z>0I#rCG}~8snR0C2yMQEThq!ZuBY2eCo%%e{&BKH`EThqGRAU*9W+U@ny3Bi}M>GG4lYEFIAG#!;Aju~#$>&J&xl8g7lKkV6 ztYZ?5agxj^T*Wn*L}Tfh6#ldxNj`H)sv=3%B*|~f@i2XvM5B3_P?t$G+KuW=qS0(* z-cKia-yDrTLXnSLkxxbJGM~6IpQFs@ER%aX_7&26 z<k!B#%XfzKK8ZwPWyHT5IG@6af$AvTx z=hA#!NK^Qkap6lQ(tPI9e2Fw)nl!p=zCoIATpIia-zZaJo@Us@G#c}1Li-hbt6Z0D zG@8#8eT_C>yEe7ZrdHDCkE76L5Zh=p4-*=(jYhjshix>Pjm#&7Hjm`md{Ssr_%35$>9(#5~KenQ1h}X~vl}^_WJZ`ApF_Nb`+LQyXb& zCuvSR326p1jYjh@p)u2Fv>SDqMx)utd|F8JXfDmCg*1h~ex0QG0%^W*X}(69uU(q& zkmfs=CLm2HG0!q=VH%D3G|>XSpw(v?jph?Y-=fU7u1p=2sgsn6^q;X!{e)o%%V;zY z6PmD$M!QjuWi*MR z9?wPjJb%0Fy8SPsC%4O2X!Dh8^DWwZ>)ZT*Hb1yF<FiFuk~54O=5-!J>{{cJ;~ z(P%zV^gYsi@6yymntDl^H#Z{9Fs9LH9wszn8jW_N0n=zS8<{T(X`aZX`68cYH}?(A z*GTiVOY}oijm(z?`6qMoUl!!eH!R;k{u?L%J>dXnvKj?1^B0O@Lv_+ z&9@`p0{&YE|1(^FcCJNmEpo1V(^X^a`WIb)g6mJtwIN&^Ca$~jr|u)^s?nH)EL}C) zjmC7>JF>8dgB8s1vPm*QUl`-_8Z4A{mA>>>O+BBKeb(V&D@gw<#_ zni5u{*~olbfPFRx`)vW%ycGWc*dHA1Z-D*H!Bz%rWe2+-VKv6EtyTjzH0S#djplr! zUqSz?qi+KGCJFsk{$-Fcq}OO3CbTBKM!V6B^cu}Z=DPy@b2<9&3iRg1_(#zH=;(h3 z{qLgBy=Z*zUo@(qL6s8obi)2@pfTSd+KDe3zXA9+2iz3EO%vd>p0HIb@qBvR(Lt{xNQ9eRfLDhJ6xL{TLVF5pv>PoctkG;_ekusRloS3bFTBOQrT7)XzdGT+A^f+5 z`8R@V0JesMJ(#c><16=7{GclO3$A}T*DPGKiR<(waGgk3jpo^g4s_LMH(JqEquI#( zTyT9k=lXNO)x4wl4X(dA*MH#pk8`aF*P71t5V~rNU2ozm!ryTH+qt%cYs*=Iz4oaQ)r6{tMTCoog+))^e_g(p6*Z z8V*jAME}6`ALrT%uB{T+XAe(*k}#RB8jVTlL|2V=qYYg(nvKk_1=m+|uD=#s&7TAP z0oOmA>wn<-AGt2l+pvHAD{XB6*LJ{%5m;jkTzPcbCi)k^|2p8-0B)TCuR1#YNx~EY zYcx2aGl4bQjkW~VXf`sx6@XvM0smG2HgCiJ1n{2@_`d-DZvveAFSR_OSKO9W_gKAY zOYzF(Yq$SyiaL<49yUx(%e;B+^f=fb>*KYcxus3#B#MjdqmQ zXf`sxC(`-f0`t2$8vO;~znpMgc-3`YN6<@S>~-tH^r=Swh1Y+bS6g_sO}yR!dYDEp zjpl4ZS9)o*8|~?((QIT2|0*@}M()bA|0*^58(@DsuzCQi=fI96n8rLTnssL^a>{w^@Son!pF zz-ZnNWx$xpmNM$M271PZU~E`o9y1(6MvXD!d4{n}L&R%nK2H?D92|2;Fn3ItcjF&m z&LXo$^Dv<&nKjyt&SchTHZuPdnBU1U|5IQ#U%ewRN7+2fcoA3JdBghDby}`R8m3$i z^Jq~c1ZY%Zj)!9zKx6)qqRb)bD=^ByKjZw%!oRHZ?*#u&iT^+R5zB1)YqZa{7yUKb zjV|=pXf`tc7X07M`Tv{uKVbV`8&7@^P^MY{RL(`}j7Xi6NY9;=z7oP5M$%}XZEr@>Xg9ht zl18(U`A;Fzd$~yeF^8iJ>SSDdxpnjlD%67%ulcm~lJ2f5(Hv{e)k zB)A~u5v05e(gi`fBtedtmVS^hmq9ezXWNHCG}?`B45HC&Wd553iT29miu|{5+t`;a zgo#|3atKo{t4~u@ysN$l=YBuGyKjn+smNt&icC#Q%##i$Fq6hO(;9y3m#LV(*E1E( zr-{lUV_BE60y0)`8M`85*CgZZGmvo}Gio$XBlKlPjdr6uGio#&5q>|NrhLY+#Zm6R zTbKL$RgpfVa5X*3&AD5T3}Q#_SQ?!ZF4-RLw_p`?tl~Om(J@xsFBXSmZiZM#svo zV^4JKnRKkd?*|sKqego+1KCld*@(&(D&=pmvO2C;N!?)W3pZG~vElbQ34yQ7Z#yHT8ywS=dPRrKaC4Z7)YZ%o52jE z(QHKJ3xV=?P^ zAdPXLdl{$*fr?z9$_P~11*(QX)m)%H2-GJDRGxqLVJQP?%<~4l{VxuyHKqSpbO>8% zw5Q%Lla3WMnhnJ&yl+%V-ENAP>#4s%U+9_KZk158lB-!2HLGU-SIruzS;N(AgPLth z%o7f0u%^bi=4Y%~5j88inpIG2HLJUteNnS-QgbnDE@MrNaZP;>;A;+LO^x={ z`?ID-vk?^)YUc0FqWIx-Zx()LoBPe8`ETbcqh@7Svl?nv%jS*s(^31?ttM*LbT!+e zX4?|;gu|JvsWJaZVepzLeW^#4kh7A@Srs{}x|}tTvxdvr4>|iKIln(X{UpLp%&9TX zsjkIgy}3DuF{eg*?gN-pquJR0Yhe{OcXQ_cHfDTt7J?=>XBFhE;&N6;&g$7ba?~#O zO`UnWQVT(AxuES3v|WjL%Hb>q)fhk4r@TEYqi1E;vl@C)M!tAAbV;w8&Rc9`Ugvu;)m1iS)uUevvP8KRz=UMu4fJOtdY$d z>u)#Pnzd20wyW75HQSe%CmhaZO^tEQriZ2>qbjIb#nr5in$=y+TBupe)f|AD1Cp8> z&P_jwu!1!;rfP09HAk?fMtkamSW~0fh$;y&byu?%YSzl;jrFr# zdvDf7&AP5;N7U?CVxDj~mo+uUHLqpOYN%Pw)vSq{HC@d*s9DF=9E6&KlA8Pv?S)mW zsWDY^lc_n1H8t8(AHtd%%|=wUP*YuV_om_{_hzAIa&Oi^%^I#|ZPcut%^UCTYt}=} zdah(ft6Uu!blKMK9 z|F$IkmvS?26o=7lsL`JAP&U+PHlk|jN70loI3aaMR!{E8nrK+lHLQb%b+Yz>>Z4tK z*RC_#buKX%L=z2yF@g?6=EySivsH=CE$KPIxTrVY@r zfos?W4ZD<>Cmb$dLyd96&)Kjh8rF0T>!4vB*RVbs)^`nuqT$e_;gfh0VHY;kh_fkQ z9L6%CMrmn}>e|9MwXRZG80>(6xSpkE!=uRi+K&)Sb~gl3Igvu9-7s2%^IRvL)UCLnhj5y9msz&Q_N->aW-l;p3O93L(N9A znMSh_)haa0-*dHeTrZmX&j*(NaeVFM)~kzjbzQm!NY@~1AE+_XHFoK`BVG3r^YNjC z=`_aao?^N>NLR5&`quGdR z7t$$W?sikDTs-~0i$c8QD_%XMtLM@+M7oCAJgk15s{M-B1PPnCggub3M~QjD;bJD# z7$HQKY8#Dp5{#uz5lXf{-+@I_DgbQh{v zau*gNCU;>2By8XkHb%n6**xq#pRgGcHggGkAz`l)^Mu2tOsFycNTKgq{s6o_8rF9W z8=+w%*RUxXHgye0qv7bJ;ZFP=>+9H1BTgstQE`~eh#Ik?uYzM4QKQ+2>J=j9@56dJ z9^Z$BAFD<6ll!nCA~tjpn;>G7?Ei|`91)wlh`kZ9cZqqz;W9?l7)M;Qju9ImVgnbk zF(Nj05t|`mGZ%3TB92KS9>6~X)*n=)zkAR9xkdVYVeUJ?DU7HQD~dRd5jC0(H7eYR z3aC3#&5}E@kTJOv8zEvN7qKZKHqHL8h%FGYg^Sn+5&M*wCmb$kM2&I8SIwQ+5D^=? zh)oc&iHq1A5u3Y+V-ay|5^)9pDvbVgA{{aJhZQ#BR7TW@6-6A+h#JjC)FAyRn(_(t zezfpcF`|aao!A%=8@q_j5V2X-K2R3%vMyd<#OqsPK0aK*cpCHZqE2JdUxcDYXxGTK zYk@W`T$^!dGcIZKl>Vtp>X#Af&l=Kga)0z-+e~8{jaX5e32dX$Y>2*agQ<&dFr`Rt zutJ^W25W*gO3BQ*CvZLS=VMf z+Kf-yJjDMLn*QV<-6r=33AW92w$X?cwVB8^8qG%3DE%m!3inOnhtE;tr$y+y8}HD`aZrGWAEM{w3x)hbx&$W1Q({W@>^=Ob4gv4zXn3K?5v?E|$%ySA>~Aha7)Vm>}x!*&|;?V?q@1DhjVbC<3q z(zSHy+8|vUmu@oBO-|C)=HGtb%5)m-+014-jdo)y(`hstQL{q2{2ka#$KyM&@NIY0 zJh=n2NSAf#S|eTSY#vrWO0YlvYKMgFT*ARfIJm?-;czVzYRo@U=)8fqUkfyB;TpC= z!&a_gTQqFz8cspODM`b(_%D(7U_*`ebmp+3M!PYM4KDsw; zQ;}|JlCC;`chR0qr_r9xT&B}#H>NY4MzayMD5T5Zel2u7zWoZ{Ye)K|`M>zt3h7$8 zbZwEYZ8nCzGQ?jEq9;TAX*!@_2Ule*aijLxPt9b zu)Qld4F#tq1-tQ&%=cnJjrMHjv7kn~F@ps)nhgai+Y~qE>~5s+qh0lq|Xb3Kf(4uPqw3bqzb9VTY`J zpw4L5*|i&ib|Xs6$A_EPPGi1Zw1zL8ZIG^wOV=Lh+Pid}kgk(UHxub*Ch1WDxcU7#)q)WrpwjX<-LK=1IE zKE(2*a8&TUrp#1&QcKh+%KM~2Jc0id9u1sf?>731zj`QEO zjYgc&CFYrgTNy`V9A_8aJ?#;vy^GTcaXPs;T@k0Ni!%pt<|J{RVVnaPMt)lP>&ul zv3}vy4t|h47Qx1rn9mh%XE2TNXSV{6;vUxfEWX=8@swaB& zOnT{8Q0<`CIP@AE)b*A>0Gx?Vldt4B63m-`hb<{zZ?Mz7vU zFa0L59o%0N&}%}8dGg^d_R<*l`iS>e7xe1ldUbD@eu?hh&^%1k3q5`7(8&T&%&iw7yS;ynsukZuks7rGDbwkc>E@w~V?3pcn zplE6~ehb+LA^RjDui0V9i3mBdr1Z1J7gxBOAvMM!_vVe)6(PI2kUbExhYQ&oA$z-! zix6^A67u;K2zeMoYP4swk|8zPjU^1J(QK$w;l5Nv-IwZ?+?R!v$$i-!A-lVfy%4fj zHV>Qo`v&H|?2DXzlbqM?Fy|!XoK#|-e7J`>HO4vHGiNvC?B;UzM9!WrXCLJ3<8m%W z&c#Vi^Pd_$oH;e(Z1msp4y)KxBUbb}yOcdOnvJMyp=bWa?5gAOjam4+JyEyh#_WNf zJzUS;=-E4)m(BflMbon%diG0t>KFa(;B|H~dQL9+KfdldT&l8bz&Jcxxzkg#&~upY`7eJvU@d#fh}9%|j$=<5 zaftLB!JaazBP3UJeM(EYJ|&;OKBJ=k`mBwfwN1}@=vgn8lzk;%woVPvw4rY*pZS-i zX*V?O7FP=h9%WM*llQ!qO>3cPEomzI*44EC_^XS!bxqs`h}*!#9geueecVR;6L0Gn zS4J!=5qCV}%7{ZG?nuU!Q61rGMsdT7wWi#jyjY{3+)PV81J*&>Iwoy>q^%!I0>7Fy zZ6l;@3SBG5vxfQoxq|p;t(l1ibZ8qN4Q#1(e8hMtDH|YVgIE&uwX7){ zBV}Ws@{X)2dmv?xxH|9P5L3#Syys7NmDWMZIwoa(q^xgJHbTlqCgn(^9O+Y*9*LA2 zm{LZpCXsR?Q_6@#B;{zPlu;ewYDX!>NfRt4`!{~3w3+N)e3?qSXahm-Q#=&u7|qy z%w^jUQ5%}5O%Sz-i8>llNBgKV=4NiOU=yRth}9&bPGVFUafn16%cwG{BV64mYIxb! zmD?q0kMxg>Ts?oqHbBn?re|aHY#h^f)C?V)`HpvG?bsU~d&kw+3Z7&~8Iv7H@+z&5 zj`dB)M(Egx9rJ!D-$+NurY7VVgdF2TmggT~-OP|O>g7ykM;Y}I3AE z7pG)Pl$@R}>95O%=-AM7Y=VwWV)A7Q=5&$IZXK5GDsPUe&3)CovsUecs(s>W3BgmW zDr2(h7*=h7strul#;Dp@RsABzHAB^Ars`N!9qX(9#os=;m{n!e%bCKeGU_A7v#N~h z2vQ+_xVz2l{Uzd9SCY9mv%DXKP&C1nrEm(h>6El{+DFM3bbqJ2@c zZ(N;z@HC6c7~XF%VIJTA(hx}-nxsvTw24akevWI7q|HszaY#DOCw+{6(cuy%l~J!} zDwE2nkC?!uGO8n7gD9!QOb-jyY3OC)XSlgh6E zW_jA~hot@D>hyzWm{i8({l3kMv=NFnGDTY;SPK(uJc5n)!EWU5I$z3QGU~IP#$Yn) zBPKGKjOqy2FbWo4gAL8?P0*={>C_yZn#Yn}mu2bH3Y}W{PV&j+SvvJcr~Ywu*1=(R zk}-L|AF@+RbZBWhOhAVTzC$to^M4CF$f(a|Iy=aykH}#M8PyT45jr%I+vT$9mHq%- z*VsQ6Hbs!8CP)heX%S1p?9URUHG;JELF7ZqvjiD{AOqs+^n+&^M8@R()@z^nvd^_b zkX9zhL#B>PHhmRjSnIpN}eUiKm-{WSEnC5#~?B$@Am|+kfwMflebo6 zzAL0?j%$rztxd2T1k3Tk7K}r%Z44$O?nYk8&txze^%0X9Oh$EtYZ3(uAIX}??a3=B z^=hK2zk-@0SaTDs6@s;j={stROl^H8`6ZMrnFb-#pt$;4!Sl={V=~i2bu$HBGh}MU zO!DTPmKFSF4cFeXg1Q^m1{vF!jFXUYlFwL$Z@##U8D&&=6U<^p8TAoUm{CS`gligQ zl%R?0POACqE(+zdaotrG=3pFwLqs9 zrc*m~YG*o4L8mFc({TP)>kf93QJ?M{c9KyaF^!#MR7XgL=y^;U$@L^z{Ph%-^4C)< zbZTWfwMD14F?~lJ(5Zv(B%cbOrPEM!8X8w$D|m^WWDGmGNBMH1B{H=%nc5>$dy{D@ zGEMcF^3KnE>ms1P5J-nRq-UmL{(qB}q5v#R{ z)ef=R#X`PL^0n0WA3GviM;}c-`#npvVTd*?u9grSVKf<&(GD|OD@1E$qP4A%`CQhv zg1Q^m0Z}`csM8R2nvdEEA3zZ7VpJK`-30R(RYrZp3`Uhv9U--%Yfpm8wI}tG*PhDi zufR5l+Qvj}kErcqA#aY2+6hrR`Ka;%@L8e`N7UhQwS?ehMwKxcbw7Rp?ph;iYZJ8{ zqP8|GpdYwHS-x&Mt#IgMwL+=;aWve!z;B_`gYgaUz}~x zv90OY0UbNULeWXKV`p^i>^sUwzh~(<0v$)h)maCxu%nF0j^BgOwL!-=rek|_Y;QVt zLdQ;~;|z41;X6J!8IQQT*-=Klng#4AqdsC5JIbhzkXq5jDGlY~lzN%}_>ouD?a;BE z>DUn+JH|rMEI;Jwf{tB$NBPkAEFDLp^d0ZG6dm`lql|hr3)xXdeZ*{blu;ew+C&}0>#>d8F3+5O(*I0%ZT)50 z9y!~aoSl%fQ!Io{{Pa&fXLd!-u0E%H>U)-)qmXk{T%COI8gt5+%-Ij0ION(PXFHR# zBXV{$IlCZd7n5@qa?bKO*Yo=>dzn*4y_!YLDWg7O4s*(=j*wc>Whp7;vXpv>ptI9K z{j+5U29nrC)>DUDwyTtSzbw|hUzN35ye3p)5&~Z#$eXZaPc9b!BIo{06u>&%8Fc~`| zV`r1G8!~n?8RsD59G{VY{V3SSj56xgEMZ0&^%3)!QATxyREjP~Nhp`2RP&c(6w+Ug zoshAU$=DScyT098%-9hbJDQALkg=x5^)Dszd`i!HqW*mo%cQvYQFn6Crz= zkn<68z7KgDf84j9A!XF7SLV61q>Sna*C`4aUXPvRcDWwi!!AeO`)1#5))h6o znwq`Qs<&@7HfyU1Xf+|O&MbI`tz-;a1s5*oOPMZ+)y2f>j#%AItX_!K%fwoMSPOit zoL+eFj5C&udO0f?OGbUfBF2(Y9pO47R_FBXu8V)v?1n(yOrSmp)W-)Jmo?Bt1ezFE zXA`{3Kr$u+om7y4x*||l6Q~CQ^)P{YBT#P>XdwbE^nspZpaTpfqh8KR29i-9v6z8m zR7XgL=wVUf$aN%H)T3E<1nO=A^+lk*KG68AfpQQiC$8=*_#Xqwn0&N*fsc0G(5D;w z6wh%z(Wj^B(+7R}m_CcpXOZu-aw0CEtJz0Jy_!|*BcncI3H!*Xj&NP0KH;NXSGipt z?fRzwsDw7{=aYo5N?1Emyuh}BKLec5CDq_`Vc zRz|&?bu25RK4K-y%BYTzaM3j@RppwMkp7yD+WKp@FUs~cWe1?_fLK_zVfbjAOWDCF zJJ^?X)JLphS{c<5u6L9+yl8u;Z+CtC)!GkD`fy z5$j3(?&bzYl@W)?TSr$js*LIgNf%wO5>&2NNvZyI*dI~*o2Y{jbx?^m+ljnf+j{sdie>o07xdEo!V3Zpi3(GYQ zFUMTU4MVwMzTEVzI>2MHa3<~uj^tamQf$Ej)`SdM@Yfw;*`8{aY|8taYm8- z#W@TKhsDB#$%oBc5{^W|kv`$9tO@5L;oP`7&EN|rlrc=`D)HhQgo1;7!E(0XP!t?$ z3XVX*5vJf;6kO{I-ns(?Z)ZUn^|CHuK^gTC>se4nb%Yxj6-@40xjlK2MnC>@gZxE0 z90iBR!h%i1C%#+?jzYmvzToVv1?QpQytq2e;7b;iF8rFzxn7lKdw$P_=^2xO!j-5{f4055Z|w|?Kd3#hMRt) z&~KFKw;ui0`+mFl*VXT2KNX!`iPC}C!;#T4UYPSSKwf|U9P}^>6bTdh`$0y zqTk3^C@4Q`&iL`Jn-NQXsM8p<8{^x}&Dw4O+AWBy6AZp)I~kMh-eJ3;XgAcii`jM~ z&~AijHyZ6mn|2$}Zi8=kgzXNpos4=}TiH%Vb%el2SC&+fXEzCvXtN;Q#$Q>ZP-avt zJgj?;YBSTf8H+Y!eVdV4+bl$zg>iL?!8dFpW3tT>wi$*t!+e`6w#`Vi8EM*#L7OqA z%|^7@=-ce=jmO2i*hWUZtZi%~qdLM3joO4)%}}{LdDXb+yP?DURWqVg=F74XrSumX zjdr7B@`Vb@M`)XRvwXdAs5j2nJ2`8;MX0wZuI@Ydmi1&z);oS#rk5Lzdc%Fa8n)gj z)Ei~$jYYk&rrsvh+vMv#Gd}Zdg1cEyM!l@dSWiZEgc}ysla7fiOJeyeE9&R3tdXcE z*NFN?%NW!f6AQmg_Z<0jw#-Mx*}mO)v>Wf+mCf32G1@JTt9uT=m>?aFS?)N&)x zZiH`lp=~!B?M9n+Xvyy0?t^2&=| z@w*ZJ${U4t^2STmZYH zBav>Tq^pUvV^D02DK;L(#+zanqu9m1*l7G5B)FHwWK^dS>|ik&)e#aTdLENna|h@A=xOCY%G$EHOVF**#wj95+u9CC!51>Y2L?VGV0arWHK4m5pHCZEWF4@%I(RE zEP6@rM)`|u43f#aDOIxZNH#tuU#MV?B-7F6`Di(amgA$nm^IomL|YbD_Z|GmXfh_F z?U3IaO@BMejYhQ5CfYbe8)u?TM6`(}+NFqgsgJg0ROU$p_cNM|dNsQkO-6NuG>NV= z2`1N>H1gM3l+9mfV-Zc>R;i**K(q-l`7(u)(R8-?KHDT@o8+?{$(n6BvMrCRdk=nM zHW`!I?&GyK2HD1#Y~zt_yvde>Y&j;|7G&Gvv*j6$Y!5J-jCwVfGn%8l{Y+BjsBH(RP~6OnCVEc`;<)hEHZ1wPqiB%AD$y`DAM3M5+*SN9zJ z%w#f#$%6S8^C@jCnvFHhCZO2_(`*u&O)|~4qS;p8Y|mIUdyvg!)XUk;W-_WHBuR9s zNiVt7BvGQ;!gMu%sf|Z7dH#ah)RdIFC!LO_*W3t|p`0FQbJnD@%^>R=z$JCpGdQ(ij%TVt!U$4_l1bLYCWK7nR z>(18O%X%`ZrAwUX%9C<(-)i(*9ar}q{KkGVCi@+fD?j6v$prM9VERo$ze%RwRP>u_`fW$Q?Y`dz`8x>d zlL#JRKN*w#RlT<3oBt(-pU8>usBHGkgNY|0kmilNj z5N(E!_EFYoYY=TsT-|T*JEO@M-gD4yD_@!9pjwWpHU-tDm}=8eZMvzp6V-P5YQHVb z+&aNytR`c!T6n2VSC`tAtR|ycyPFtQ3oo^a$uBlI{WsrSj=$n2Bc8mkQpKBwc++Ab zVdBGgij0{)b;hVUiFbc4^YLaP-b^3w)U5H=BHr4#y5Har#*;A_ui`ewn}m3iOuVUx zH`TVAVi8BfOWp53(0nS0(% zM!U(T-AuHZY1&+lHkbQ0XY;#QkF$-8`fT?zh>Yq8Hz^7dUQLtacF7@EQ}h?!++=?> zO+^rS-=hjLBMRb1#u8;`#6p;9NaEwpMv&P)$QfCKtVfXbadp4JaR!kw8Dt)VOhJ$- zCde!VnPr0PMv&b;$PfIuswWskMt!z%29Z%6A>PpyA~D2K{QVUYCGm*U5JcXysDjK) z1(6?}$rq9zlqJ5OeXo5FDa%X$yAeM1|HvL zn8&x-NH*If+k<3#e6p%|Q(y2TlgX%8bAZWYR7bceQL^wFnj*K0vs^>b?}oUk{u-K& zWb$T3m26fjnf$~|lF3iU5-;B+S@vji5pAxIRyAw1jfl1}uI@Ydi_v5ZqXmVx^I2&c zs!cQ1W}@0mQ*92a%`w&XqS{_xtuuah7d*vkGV0}A&1y2LBP2?6p-C~pmPr0Wi@Ny> zZ3e2z8x>Wx*{N#slQQ{2@^i7|g|;}`W8XY9o9COIleO6FSNqZ zkEf^m3vDKn$vYHPvN@?_@&htSCO;4>I3#~g)?o7yY`zb6Zq{I%5o~i@-EZ&@gUJ}) zZ?IEcWHV4~hAB21#b%pg^H6M_DYg&A_W5F0v)D5%CZk@?wJav1I>Jqlib=Z!v;^`O zS=7v5WV29A-jJw@%}o`PACSoxk{^d9zR=?A4~z@YY=Li9BWtsZ(d^>5y650uHj^=I z=89a7SA27jWR6KPA4%q$Bv&HIl|IQM{Pmi{Od_K`+v}J_MsB(Cl|_>WO! z%o=3@&=(l=tAKu$M}KxkX4&9bqRXhy=6a&bsE!cR=*dRF#Y&9*br7-p>tGJhfVDqC!AkLV)G=%B>TC%78Zhi zp<&+-_Whpy34G>#@EqA?)Ms-8*=1BmxLFZn-X7YT8@0HBjcZ(KH_4KFZSdYWF_AM@-1<7&p}?2%NUXe_wL~9vPCdo zWX$6*k9%|V(X7wYTt9n_D!vusTjOd0fup#L;r+U!+~kV^zSw{t0Qdn9{v6-c@B+bQ)Ms-O z!DUoOxH%DcxXI_p?Xok6rvK)ao9j3Ee1Ok4;EPh=@>3rHm!I(@zSPp}k1I<-zSNV~ z&Pu)w8`ekvoh~Olm z%a}wzcQ??N0)44LzXs^nc=W~m_`H{hE~7r1TZk^BI>OD1(8GN`Pi`0T;c0R=-|zE< zKwoIkm!#0;$1H*_KUPURu*}T%P`(`C%RP9@tl--LzCErM5ac7cj7jk83BC;A%MAFn z0Ke9Q-^TYO9wE4l`fP3`xQyxu@r-u4V2hLZCdiki$^9;01n@-$d}#_?encW)NPZ-e z0GH1=vd^6>0KUS5cgPC91K>O2Y5_rhg3Fi$e}dr40lwUTUkC8(Ja}_{Hqgrimr31*mY-rIyc3^6pZ?i~ zZ?_WOE4_Eutlm4}y)&-PKPW(N8I#`s(t8EGR~YZ>;eEaLo-3cZm+=GKSLiLHKAYR= zEu%WZErj<%xm~M90H2i&d=|pE6i-GO8oo;;2H1w^(jZ zUKRzSZ?i4&m&GzvSY|4$M1_?xeMc9e!bQGl`A<{)A(#?o;vyb#3-li11!ALUd)!fBMGO8oo(kN1RB`uZPlUGvorY^V4 zUr8$vX@!Zj8j)7VQg`GoiX~qYtVO1^K9l^~f0j&pk!f!{_0^JFCMe2GGA1+q!%WMO zX}QU?3Yk`!Oly#7jmdNiGTq`cRUVnSSAsX0Nk+YzyO~Kwb%a!io^~Wr;`NdoA)(}H zCkhq4SVE?iCeuYxCMSvH3rQUHjihzRw9aR`C~KxGkm-uJ`dUFTW|A?P=}6a1A-5VC zR+|iKkzuXLa4Rz0>N6bV%dxkZK}LPH_b`Ku>Ik|8l#cCWu@dFDw3?@(VxWgFZ_eHqmeZe^q&K4Yv*-|qUjO`WwCe)~xzhLH{bFUy}MVhWf#g{d{S=8vLsb|61^`HT)aEzrpa|0scEY ze|x@F?OpQAsAz)w$uFZi!mR@Ts`Tw{wST5w1Aci(QT&_0zsd7&%gVnW{QC`mDe}vh z-28v?p=TX**BRZ7(A{Ws?}YB1UbpTxZ0`S2S4Oq+-~sB&sE!cB=y_IT<)KAPmEKzD zt~I)wp}X1ZZqKS4hi=^HmZq+Z$<3WF&dt3Bn|qDf-0Q)=-tcb%|0ctK5c~%{|L^#v zhu}T(%c$sr2gxs^I>KEP@rREs7o~4^Yy9S32mW=2|6=f8?D?IgxOcE8Ze?iX~m z``3eCo-ozzmw^8g&mYgqe>M28HvA`(U&bW=R>i*#{Ob(=M(}Sm{1=1&V#9wo`0w`o zr{HI8!3X4*QPBhslV3)4gj*Z&hr54m`gYgXKeKKC{|3W<4M?vsq-9AeWAfqpA$*96 zTMyCoMsyQIHyP1OAbN=ry$7QAc+pKg@NoVJy=2s0>)^F6eY;!lA1yY*Yoqbng6+CR zwkvE%4l8 zJnw_&ecto#t?+z|o-%5!4UuPfJ#R?g?)v-dc{4mW8_#X<+$Ns#?@gB{@c~1HXV0B6 zZdUpaBU}&K>kaKGq?IxG#r`GjCeUs&w3mSP5<|Ncv|A1B{h+b42TeRUUu^ zR6PJ+3ffBz?KaSEGqgKEyTjAICqJPv4=6W*_9jDHiL^2%Y0HszD`>YG+U=m-ZfG9@ z?L(gSe?2oVo#08*%BbNkj%dTj;)~7gTL8Poz+MK}%M9#J!0z<0g|qG1n*n>Xfvrqf z8I!P02zx0WE-p0>7ux{8&A{&f{0;;EFyJ5d@IS~0HD&xr^(n&3sNpXG{3Yqz-3R{R zVk_w7+dyj1ZwLK$L%$33yFC5*+30Tp{Vj(6RMN{B(g%62~Dqr zt=isghuL;xwhLyvjM<|wd(@ll=7*O*Lo*rminqXQOZs*<#G73Pv&)RxPMGa9X1igw z+nd#vKLctWgKvY`ZN_W|%yt;F%VBo8F?$SVk9jjU3H$6Y&1BSOTVb{}eY@M{ukr0L zlkbM9eYOi`yNuZ$nC2{cIH>SH_y33gE zf$1J&`Z!D<_ol7q!Sp$r%BaOIi%i280hgt3cO(6^y%VN8jp=Tf?lz`Z!1M}lnm3#2 zoiM%AnC^h-4r6*bOfNU4dttiQm_7m1C%oz3{C(l)X)2>O-44_3>D%2HZ@LSnyNu}` znC=nNA+q1M#By9i|8^e#v+aGr-RE)79hBvP^B`~!8r+@0-Dz-l19!Kv6YP+$({5rN^x~APeqYz`e`h z?gH*EgS!W~dkpSA;O;ZHPXYHSk9#p*9tSTHS4NGyGr|oY4R)q)cR7CN?gs8|gL?&V zuMk{*`|v85Ugb?6%=Tz-H%#v~rkBI?a$~v|rhAR)l`y^1m_7~Dr@iTVegyDKG?h`W zco$4}rEhl=z3Cp9?lGqOV7kwk?uY4qF{SxEfV{^*?gr#;19=4?uP~5T0rDyX`3xYR z@sJnr8(c>SDWhJ-<$%0AeY@N3UsCM_K<+h=R|4`%0~rTo+(14H$Y(v|;t6>1^a>$m)J%I)kj=t(-Rv<(>;vRJ1GyiN z`wisPfV|p3-Vez84dfMoyuv_U1<0!mLJJZv+`W@9Z_V zUkOI}(Y4yIaWKXW<27Ks#xOnr#s>`JJ}~YxjQhd3-!NVc#;XnE^I&}5Gq#$F{rDOg zWz-B;fboj-?QXh%s<{e~R~g6yfIMIzuLb0_2J%5bK4>7X1mu+lG7iYNfxHHg*BHnb z0QrK4ykZ(4UniuD8gd^X_oZ)lvpnQ}K<+n?R|E2D19=@FuQQMj0rDXOc@-e9GLQ!V zdB8wk3&?8?LK!$_Ub(5k5j*X^w~kQr;G!F70aod5wX*9+1}? z$cF*>uz}nU$o&TLYCv9XAg=@Dbq4Y!K)&Q52g$d#GQMa0CLv|i3|B>v;UnZ#>D%30 zzatL-@_>Q77LeB($QuB8gMoYmkdGM1I3VK&@)|&1V<4{w&UUWV7p-m9eiCVqz3+w_uAd&MI!Csy)eQFsz!bJAk|TM^g8>w4pL6TEIRUXQ`+ zG2?YLyskE0*TL&L<8>pvZZux6!0Q$7HJtBhdWT*zYOe#4S9qZwNZ;%?4jHIx0CkOlx*ky18>pKAb(4X56;Q8wsHwfMvEC(=j2i0d2+9ePY%JkX z5B)a+>P7=~3!rW>P>%!ZaRYTNpsqDgHvsAe19dZ?ZZ=S_0qQjmb-`#r{f|&GYKChf zsBlMJlfKvz;mfV#;*-3q8%4b&5Wdcr_m2dL`|)Qy0;(Lmh-s9Oxw>wtRQLoMJp z2;L)?q+;JL-l~neTA9p_IP;WYt-C&?@1JrE>>P7gp{mjyo{l#CkcdO%&DzTMprU3!4J$w1u-s9O!x9e}#S zKs^nprw!EYfVka2yakB2Jj6Hrm*t0qkWoY25J5OWkV{LJuP&{d0dcc|xD61u352|g zaNF&7-S33Rokrvth&*FNZo<~N$!wiFAa;ildmCbJd$H>L6yH3rMIebwD3DQk1Rv2< zMsaJP z>92n`An!Ji&jIqexc={N1>~&;@{S6bPw;nC(Et5ifWFH>{}0gr^U&qxLvJ$v(G(C` zMs+vAQ9{e8j&QdC`j+(V?pFWIayzJRH`E6~eK4l);T}-mW2m18_49H4-`@u6+YI%c zpuW>k-wo=!4fT7Ve$P{{<8LURL~0q;X$GH?T1It*fJVQkd%gVW{r{ z^<6Rj-`@-Bdkysqpnf5)|NGlPeY>GP2fBejg`G=tAb zEu%WZ-4;=YFD!3M-|p7?r?fjkeW#(m8`O8l^gY}M>iZ1!i=cinuK)WxKz)ayz6;cM z8R~mMeXpVZ0Ms9N>T~%cy8NV;QJrS+IjLn-N4VQTeY@N)uczb_VN>77y2C$?9EA8m zBYqFW?}_O_abBf}f#VfMPPL(+Iwxn2hQOcSj^9 zc8SLU0ZN!HN}KtYO?N@;E+cj?#O{shJ30cfBXNEELF~bUW)I#2(R+;O{Sdw1h<*go zkG$wOzE!p$MP*c{8GK1m8PyT)&PX)8-0w`^?l$_%{ccd+Z7A;p<$W=I4=;oA<+#56 zUQpd@s2%{-1BU8jP<`yF%J4lNg-9i%I*s5fQpu=}a0fwkFnzm|KebyVCr^&M2UPbM zs{288e@x%QE1-HMu5Z5&RQDOG2SN3qq51?=pLnY7{84XVQpu=JBlwzBGO8ooU7)%v zeY?BcKcw9Ys(TI91E6{!rtjfZP`w)0x8Dz{`wi7YpnAwq9R<}4yeKJURHqSqOG+8l5$>LdGJGt%Cw;rS*YCRfL3zKSdSA4$9Z#`u6)kd7q(t5R?xZ%11!?h@t!pl%ILZ{QQw_F;dE?PBZw9lrpL#1T5N> z!YI2^0M)L10F)0H%7;Pua7_RAZ-DZRxW4^@C%12`Q9uC#YynqkY(zm|} z>Nn&1_6I=yfT4aE)DIi#$3XpbF4sR$Tx0kAU(KLwN|4hYaPHp#0KPzRXYXFG)%n z)oBDjl2S%>gn&g40KzB_00O8U03HVA!-n!PP(BvZ|NRr7e8Nz^4a&FU`oDh^l#d$9 z$3gkHq5KMzUwO(;NLh-MGOE)Eej=re>InB>L>WE+JZNrz1dxvy$U}fU6w_b-NkBen zAm0JxJ8}KrKa9)&VP5`4bKGNqe#}5W0q7?T^w)s?+C#s{&mAaDXc^UM20s&8Ms3et@)K44g|AG2{ zasA&v3hGA<_2Zy^+)zIS>Zc6#x1j#kQ@7}Yr?itvEu%Wk;8#-1sE!cO=y6z><#AYm z)#LCXP#-eXPlEc%nEvmd0rfM6`aMv;7uWy&W1xP_P(K0cCk*w|pnlp=e+TOCJoSTo zKWJG}%cxE>_>I&usw3Q^5q0=D{iwP9aX>$Apq~QtQ!)MZ4+HwJfqoy*@5l9je+bZr z4D^$Le$qfc1L$WA^!I@N-b0_t@8Xpsw2bOBgJXo2Q61qPi=f>f;huiX9PtFGpD@%< zgZk;1zK3T){j8z>0MsAE^?(03s2?}fPl5U=Lwy+3hYj@)p#H&Azrx?9El+A0)oBL5 zlUhb~ggX>bhkN>vx&28%KWU(!0rWF5{q>&%^m7LKLqLBR*Z=(!fPTV2KMm-o4fL~s ze%3($2tk^0s1KeeHhS(4fOMXe%?U;4CtRd^woTkSCP;% zs?!XP6Iw=fgnJUuPnz4G0rWEl`Z+*97t>$=ML@r3pg#fhCvpAXKMTlb4de@ee8E8e z0?1!H{a+gwxBX$WmKmT{6$z9 z)e-LL2v&#_uZ^FUBa*bsa-n?|w9gva7eM<$OyA=X&>k_gpMv(&xc=`C?3w)2|X@r$goks8vVP#ZD zxWf@__=4=P+%BxWa^yooGam|`^A82jgY|jC`Vv@QiiKazy<*>y`8oVPkL%NV89px? zpWos0yZ8BOC7#|-r;m*4Zi0X5BcnRPJsbImRN|U`R*ndTre_y=0YWbrp(7AF5=#ob zVTHbc&=+xiVy{5x6(jTqg#L(j&>{$(K_MB{-30$pNJe#pdrk?-UP%be%%PCKFkghv zi^k_=_`DoT`n+a+zJ$-0aeZ1Z6w3S|#0zo-%1ODyg>syH_a)=4ckWd{zG@)<1mvF{ z@(lSK;TiAWixE;rbv{9!Dv?v-N=uCD2={#E0WyVW+(%!EFZxUIB|yGpAYTFGD=~d< zU%~IIxW4^G_`R6n_cr}rgWqe$?>PL9d%tZ<;8%ryGOF_l^3qR6b%c8%@=MrB>lfq* zY2GJ?8_`9AM<95_2)+uzS7ZAAzJ}n}aeezs5PV4lGd@G3c#eCeLgo&Ar2=l3Z@<0{ z*w+p03BaE4u!rQ2&1G!Ns)UtM-A&*KE2BC>z@jJLB&+}?U}q~>e}%sc)|UBRGj-GO8m4B-)6gC0DorCCtXB&HNsG6=JU%u{R+0Moiz)cM$t7u5J(V z6pqd$`Cwkyoa*Z^echP81=F{T=|3?2$D1CK4>iiTxX-4kjQT|L(NsotgnK!2B{GGg z-P5A(6~7B#gXwF=^i7z)8Pj+4JxsrktJ{OTG?h^u;ogAh8^-i)n7(aH|Apzl-n9N| zn4UvZ8P#b7`DrSnIzq^zeJY-^PlYhCPp73-{XTsirmq{*w_y5KOyAKDF#RE}ZVwzy zWmHGFH(~mwF?|Q7?-NJ7^G?h^u;a-hQ!$-?k<#rL3U$T$> zGF#$zQ^I$zyaCfUjOp7jeLJS_=tr3T7+1Fk0ZnC8N4U3O`j#<$7pCtT(>y0KUl`;$ zAxo9dqc1?yb7?B0I*p(pO=VO^2wAjG#Z&fa;%kVi{33p&>i6lJFn!aQz5~;DV)~AL zg6U6jef!%Gd)tWp4`Tl_VtFB!*Na^@99MSr)N;cIZ5h>R1cfLjqdLO99*Kp!@O8Oe zyyPwNk(YbJ@4~kr_LdQQ7h>Sv7h7W_8=d3p^WMX_YO?oF{baq^gUzhVCuZ- z>-<&o8Z?zrokmcYrZTD{ge=;H;wigO2otLECi+O#@4~lX`nECsA58xj(|7a>On-^1 z+k^Zxl~Enx-i7JA#`JxdzHdwem4;2O#^vkevjw zlRViPen9&9B$H9yO;D6%GO8ooTM?PyCAOgeg=l}L(fmGq7i8}mviCvueoWufZy@_E zu5bSkBp(`*d?3l^NlxQ82QMIrjOuQJVkD7K9pT=NNWxw8w%qP_QQl}5z2kS$|3LCT zL-GMgK8WdiItG$saeezoAo<9UEc3?$f)inC{7X?)e-KUh(vG_yF>t@ zT@s=AUGg4C-ZLa0g5<-PzNg8)e-LfLYWWX?-vTs)Wzi+sq)s$jDL-~kD&jN(LW0Pqej0F^b2|YZv07d zZR*RY&NnDUeHqme?!8Dq+_3M-?S8}Ni5}M8_Z#*@=znPRKY{)yF?~3aP@4QQsw3R{ z5x;~;Y<|IxHh&brZ~l+K|B>N83jU)peNQLAeUGvrxBDPs*LIg`7IdeCkAeBI!Tc1MpT_h(`~}Rv;_CLG z1TkgA5qZDJaUWqXf8_V_?RGC81^ZFM{yEq`H|#~hUevR<>I{SO1eZ}A;XaALg+8&t zMK>frCxhJY@XrALnF0S2;9th{UHu2}|KjTQpbWufR7bc^0sg50{{rA&81SzF{j0)fog8s3oI1!hITPiCbciicRPx zPxH~Eg5RQFKrTrG1!|yIM zA*zh(G=hpml~EnxK8sMpE%;gbcK5m8dS3$bON03hFu#fEdvL&X2D2P7Wz=8c3taDC znCty(V1I3}zXSGn2D=Qf%b3mEl+H4$GYl%xSw?k)XhyFf#8@`3=<<2feFf*QjPti} z{x+un`vA^?aV}418TD8A63$;5=WpQrjdA`S&fgp7li_@_ac)Lu8PypEmFX;_I>LPs zIfwiC3%Ok$QoE+VvG2b0+xly8e{HzG1NV0^eMcvO`y|cnz5?b~2J>5Berqs)0Ok({ zvn(*n`bUTl`45if6qQjeBRG|!GO8m4EZVuEDLYpH6Q)zrrv6d)8;E{mM8AjV_eS)m zTA9yLKh@GFk`Lnfw0KZ~8(c>H6~0E3uT7Kh(BwPQijgg7HlG; zI?doTHjz;s;l7HRguDDJxm}9%Oc!xq`(6GmntW@T{D3Au#Pl8gj3z&uCi&4MziCpD zO=Q&f@C}-LW14)ACf}PTKcUG_rb&4;Des#+KMybFTC$0Z>NJDX*+fQlgpfzqiS&@` zL=q&b%t%-9*U5Ki@||h&Bbxje(|7a>n*3s#6hM;#rb#6>kx}2nw`lUMY4QV_{9u~= zj3z&uCa0juDZWY5g=o@>O=MK38Jxi;GO8ooH&K)DI{8L!mm=~Oj%v}jUBC6$$@ggT zy=n3jn*0>gcl0Zo{A!vMM3aK1No6*XQQyONX!4zD@*|r3XqxwormbT0yBTh4sr7E+?h(jdH_fZxJl(<%;K^W%S zj4=Lc`3YHmGFg5_mS1D~u6{?B-%XYx$Wp{)Ih|Q#)c5csvixYW{DLgMm@LPT<(SD* z8Cfd(Ed6)kX{8;r$f!;;IFnUmR7bcUqAKCV@`K!-xLEF!CehDQ-H-la`59GyHdTH@ zmEU6euKqxkKTMUPs8ZBaIfGSX)c5ccs{CZC{E8~Snkv7e%I~Jisi<XL-lR)9m+`EUkSg!{1;<>4Ccp-`JXWV)0h{7c`;)iqq&TFF+aon zXJh^w%zrcHf57|?V}2UUPxI!F@bkvbrn!vzG=GZB!+ri!Qhd7c{uSQ88t>oX{k!o# z4)5c}yEwdy8}BOgmQgR{7kK|-ypO^AnDPD--hUeJ)8T!(c=Kl>=a5=Pb%gsF)ITSw zJLSk<8OZ#t$Y1@V%5M<=&4~X2@js0C35cIC;w2zn!iZO;xQu!|ze4<1BmO(Ye>dXC zA%5J5p8@eR{0=X@7LWDS$S$Kk&0ivR36OYH`6YsvOC=lpF~A=)@P7jSPXqrK;Quo4 zB>`X3z@JHY8TE>O1N?6W{tv+aVc<^y{)B;#0X}B7`nfchQJ>+j%3L;e;*mTjhvxpl z{C9}|Zp4p6{J0VS8{&T(@lp^kWyH^-xQu!|#~^;pi2n)kKaKcb5dX`FSAlpHzt#WT zh^=0o>@w=p{4HV+AIyJCqRV$iqc;({WB$SA4~YL^#7{u{gc1J-;{O=&(hx6g#LuR< zjCv`*L;QCmejMV*jriXX|J#UHg?Lr7$7>Ky3Z_Wl#t ze;Vw+fc=-j{ukK)8tgK_E@QCIA-0TqDSrU_4}*OI*e4A3KfwOSV4n%>GY$56#FkN? z;qMW4xU+vx-|lw!Eqxry$BpveQ2yH}{|Dv&jPl7)KG`T&qq2;84Sz!UPow-7l>aiy z|3dj+qkI;W&+-o<4Y%MyT|Uw*`O8rMfbt(hnWuK@SN)}kg}jHYiQ3Ut&IAdkAwEOq5T`Qe;eBWK>MGeJsY%Vd)j|UdjV-> z)Tj9;X#bSk#u(fgwHV#5f>6yM*S6zN4QR4#5avq}7RZILA_yxQ z!V5?!qdxb%Ak1qBPXggdhOh<*Yk0!HNmz%3GV0U#Cn9vhC%aIanW3ePX+O*hPW1qWz=iSTR8Iq%v)IBei9O#WD*oWf&w~0P@lRo z>U+rJGS4873vJuyxDwGz(Y*feb_Bo;3~qkl<~O*7fLkbqTRa!s(|~)L!L3bP8THZ} zaGk-;2i$xHw;*r}8r%lNl~JET-U!zTtZZGeOl;lpXA*eR;MO6ojCyGSa07#zAGrAqZXw_n(zvcB9z1IL2anr&;K8FI3&^NX(?tcs z2Wpq}m+f6D+TMZR-uX}ugXXpa10Q?FVzrye=I8*NkQ4ck)Yqf`Qew}_!WX*A@P$7!4%NQj)oI`hmjb z^Bc7QpbHr2!hkL;(D?b3D+b?UDc{n$_*Q{$72}&9zWI%BA@~+DzD40%RD6fXuk6*3 zjgkIewr>{IfqNbA{v1EYrU~6;)ExODcPHkuBZWD!Gbg3x{RS@x_kzZ~2;7Sp_u_Cb zo^UVZzZvF6%zFMH~x&qO=&EnHqIXzhkHAJ zQdstO^bq0-_`O{S#)XV=Q5Y8$u0kAkL05%efxdK5>G;-*JE^r+{1^x_|4X~rHh;ymS@Mg^iCPFe_{@cTU<74dt% zFnSa=J&K`6G3mj_nv%#+GL=ETgO+QCvykB|lc5na$cTH*pW_OlLLpP3C@K^+6-uB& z2~(jyD%AHC_VHIyo3nz9I8CWgFscw<6$O(Gz~W#N}GyY*aYgRA|f!GGcj&&lV_*424aGV#rX;WGIOYB~69~$k4!N$lo8Ya9S{f zj5trpP$VJR4vGKLLd*w7nJq+v@M%BT$sM~2~6E}RsUtsFg^xFUWl7lUCjV^|V~C5>Sj z7?w#H%J=kgHLM21YR0ex3`-cp(l9J-3>(3)kvD9~Um7?y@%X=7LxhGkQR^3Awh4XeYjx-l#T!&1iZ zWEh@o44c5Pi8mZO6px2(XegsLEEX9$@soWhWQoT^dCPvJ==Whs7?w1KWnfsw7?y)! zxs;)Nw=Gx08ZfM(4TBbZT9OgVD=v#DocaB(5`}TQJROuqh0>-%SyU)%Dl|ofroO^7 zR%pu#GV0SP9#sf;a`9vX*~!skfh*y6aw$|OWh$JE3MZQias?bOgd;>36DjCn*UhYICPg$k%p!Bl983N3ww zUs$0dE6Au%vvgD;-0P*24P>uJk0-8--|J;jp{%KJ3M!mpDpW#+N~sF+ZN6M9)I^1v zrb1g*kWnx1WK=lWR49)Mfm{rt z?k|QYgufWdAwxNnp#m~gFc~T%L*-P4#EYD1xqR2J7BbW_8QL*}jCy%xk)f=~a0)V< zqB6+8-76tOC6l2wGPL#?jxs}MW{^>z=gCoq@M<_Y89_eqI(nt)%KEFJJTjCw87d+} zMU&xFWH>dEp=jcpuZh>|Ir6_mj&bt8n{!E08%b)LB<-0*M!nQ>NK(!usemLEm_%Ne zRz{J^rbrtUY2%A*<)_GWVG$YiX_k$OIH@5Qh6G4l81ix1Q4@b*oPr{!m?D)>q>?Fe z8j75jC{iS|NaArSw+o~WYSb|`Iqr9n65j85B8mFShsisC-)M)E#teJ?1 zsjjRcqdv`YQH}8WD3@#@*GKdq<;wf(qXKGFFf}TpMrBi@E=22UQFjWwPBC7U;8n?Z zod&Pdj8{8&wew!{`JvO@=q01}Dj#_{v69^@Jbw2^Vt)5lgjYr5bt=40HC|_6_nwj1 zy~%erchCOL=6dk0XM8Kbw}SCK9e$@9zxMEJ@BJ$B&xUuWpN!h?l*ljKZ>J>n2Fj=L zML#XC;P+c4_*F7~r@`+u;}?TpEakU37r*-Ot8e@&!mpz7I|F`a7{3ni>)`!l5g8vr z9Q2@{jM}e4> z{7%F5eVVzxWAKd`-;VI@=zXX0Pk{HNuZ-HaV&og{&x%RiL1|rA$?wlo;d`p_Jp;aH z7~iV!t(x+EuYdOIyCHlV8sEzBt!#Wxhwtgew+ei#7~f9t?c{xH%)7lB ziLLBk;Y{q`g=t~Ge@}z&X~s7O-3}=kz?}uSvkY8Uz;*R-&H1?^eF-O{W;rc_3wPXU!Y0>i zxAd>=yVL!~i@`5u{LX~mnc^p3$W^s(tvCme=cFJf=duHv01MXZF(v^k8M8{^(ImN9km(XN1T6=Pft z#?_2*4;c6G#yx2~fW|WF(}=-1mNxdMc_xIM7WQ6SBj$0Bj2b z+lR0+>U*pT*s2EhT)>`dV0!|#r-$uN*nxzVQJ+Q?z*b4ax~l#m_$<(#WoWB`wwj@> z0oocV+Q~Dr)3yX{OGDe2v@+^7oeA1A4Q+MMRyVZ0K-unf zvjtY3=G)5~S)=b$o#Qv}xez|r2%iVx^F%oDdLjA7^K5TAzYyXVro>MlkX^hj#M>J2 zffScfFSQ!Ps~PbNAbx=n?+5XIUVJ6Rhf!QceH!OP;_{a{5}R3o6IA2V=6+9Chj?`( zem=y{Ply+c#1sFYO}!@6Yo^pcAD3Od9n{-tb$21mE;MHSVb7IRsg6BY-R!xV z@T+P32EcEC_xo)r{6^4EM!l?aBR?m0vgd>=vFGGhGa^C1=gx!QdB*QT_+2P|@@3ow z@~;B1%>3*x|MhCavv$g}P%ckd9pKr)c-DYt4dYo0p0$kUKzI)Ho`sgdb0j@w)SlHN z&u~9hPip3UE8}BdYxoU$K0wbmpfv$nGXW|WaS}8))H*<|lR|C2F#9I$2-J=S^*o@S zXHaVcwYEVW1k^zuwG~lE5miQwS|dVr0-AX4@T|Y5S^ciM0H_xj)LKBTC8)g0>jJQD z3b0t;?0}sB*vSB%55V&cU>yL~F@S>sIM@Tu;s;NTCZLRZS?5K7;jTQ-^SznobLabA zc_9EVG=Q}MSla;B17N)r;KEti0XqY*vjMySfEO6Rx&W+e0EYl@hzHEK0+;m|0?McX z&yN6|;K>dYuEgV8-eYM(zXNLmu%-d51Hd{4us#6mrvT%dvjcVkU>5^;ApkElfb{@a z&j1bu;7||v{Yn6iC7_HN@PY_1+<_M)`Q*K}saKO1`VCkMezlBWUHH{CehuK)AmukK zmxsWv@at;)YQnFk@v9HN`o?b<{DyhIg{$B3clQ0)4SwB>Ujz6wFh0ZKGd#P`c>2hweQHKN;r^mgHa1ok&U73%@A zo`Gx#$c6^82_T!KAjc2MezEohWKRRx7(R`S&nWne@;*E1lS3aFwNIVM$BB)U5{^W% zWoaS5(dxsezVT@UpGL-~DSVoyd_J9*-KQ6PdKsU3*l6`+qw(cq6ZkbTexu_Hf+tn)-1)Aw?}ri-eBu(*y@9=zOW^( z&xZE;Yzn`o#%~P##(2L*^qWjS8MRM6_|-Fh4dK_&_%(rF6XVw$e$7*UhjV!i*9U%m zj9)XbG&3w?!7|pfyuKORY6@9o)GYPEQs1yN0!t&q(iALB4ND8Kv`De^&E@BTeZkV# zur$QBYAD-^mqBx|H8*VIz&6ga6}%X1Q^_WyzMBSMYhc(KgRQY)YX-JvhOH&oTBg{h z=JJZRAK3aCwnkuUWY}7Ot%YG554Q21?cPhlHjQjDYPN=8YiQV-fUSvPYYw*NhOHIY zTBX=Z%TT8ICG%ORqGQqQ`PXwM$78x~5Bd|0wEKR}E)UdPwOAEu&8Z50- zEZ?lm{@6YMECUQnE3mXOEEB;p(X)KI6T4*wS!C2Kjlt45&Em$Lm;9jQW`JpCU|IsE zrGaS!m^LYxUvq&O2$+EerYSBnc_Etl=u|YvwFX>k1D6B191r&&|N72M!pVrck>6=( z0=Om_a83P-(B^<^Zs1x0u9d(gp1qse_j?S2$RH!q1}ko3Ry+wSp5#~Dgdfd0iz}8< zuefQnVp)6Q)upU6lU__(V8t!Wid$pFt!2f0Vi}Bu4mJyIj`Yo$UhcmwAlhn(U^dq% zqdtRX(Hg^7fX&h?bbI`}cv@nOEzKI+V2y3e8i!zwL(CdmV2v%z8rxxw?aUhIaE&tR zH8#f@n`f+XyuajIVU4ZK8rx!xZDoy#o!iFl+@V1}$x^vxhhc@o%nDm!g{{mAJ79$!%nIjmg)-_hXo(fJ zG%IX_6}B-eY>ySTH!B>D6%IEmY>gGRHY@Ci6?QZ$oX-`?s8`quD{Pfsp=<3QYTIIs zZOs}xV2vGQjfoB0&TiNdSnLS1*iKkXC%qUq0}r(`{6p>8-SMovfGd_!uef!zVkfJW zGnI9!eb){vZf9295i9N}E9Sl(iG_|d3+;@Bb~X#0iG|Me3%!S*9Jr7Rl~JEYn`oio z<87PtGTjRQc-tNeZEqIZ2@CBc3r(c$Xw#0uibt6hcfpFgm=({$if8#1PvnXham6y~ z6}QET+h(kIgWt>@u;LD8#htO@&az^r9gT&KHVf^Fg?2RyosEUg_6uFXPcL1}h03T; zqa7C7E@Ppa{X#opp&iXayI`SR%tFUtp<~QKI~30RxRefs^%-^pL^lI52M}{SL^~E= zLI@f4-LwZp`wWN<9-=E2+SM#{EEYP}EVLsQ+R-euI~LmAEOagwIyWlLg)ZenWz-Ap z5G~ZnBIP2K<*BXN8O1xB;@tqz%|P_5omsSJZMoPB=Jd-Ml+!u!R*2a%=Z=~+u1Vn> z|J*(fY~u`D53uwwEc3uJ&$ArnCrBP2^p7VTugvJ+&fYA5u><0Fl%*c!E~2a;D?qZslZ+mWU9z4eGHR0EAn9#L`hldMAsGmgfrexVNQOitSzqhU z0LctPG8iO-4arK7tn?(+hJa)PNo3R{eIgRKGW;VzeGE!}p!7E=gMc!~pbQ1d&8Ip@Ya*-!V{3ZCBsegh8n@J+0Cg~rMxDDYx=xrwJ&MOg@xg$88|7Cpu+dLtIS(Jy)=x63vzT1I`!L!(89+hwR(@@Oo1v@BV+ zgBxXkb~O%bALrLzAnV!}VeN~|+J|F943`a&xYHW;ni>nFu?A@qkT!WF^{K*_5lKdk zGz>_?4AMwkQzOkaH3o=d1d;n@JnY7MyFyv*7Q=3_u^R`HafW0wNH%+tx}))$Xgf({ z)TjJ^eBA}u71g``ahQ=tK(R5w#1=&nySwveqSU4v36(DC?(XjHZt3n8yIapQd(VEI z@49E7>wj_m&vTu1Ug!QiYu4o6`(2Q{D2rLQ)YV6+@Ezu_PaZOmB_Zho zk}e@h9ez`EACg$oeu@2JW$FDN&+YeL8$_iDj~{Qu_#S}(o|3?1EsQ{ zbOlP+5as*|SWo&A#Yz{YY#JrG>y#Ce3LvQZDuAtmuvGEdjQKuvGzD6=ACmw(22U z>i09_Zh*7^TMJ>U2)2sCRt;>`gslhIdW38ZDq{y7KsGB~whCaYAZ(SuR!P{Zf~~5t z1+(c{z1*k)zZ#)m>W44m{93}VrT8V_mk__|@T)Fl0g^qWh+f%LP|^{bfn^Liy$ z{fZ)38G@BXuo?ubr34?8>-U=Qs~P&GezG#ouNC}SiC-o7RT94%@T(zyz2Mg?^m~xs zP(O%%R=R$PEWe&fzl8WzfnOEzs}8^FDZhusuNM4jg?_2unvC;n4ZqgnR~del#jhs( zYKmWP`1KC`_VOF*2h-0=*RN9AFL{8iBzje$S5@?CK(9th&nv6@Z*BP14*gQUGa2XC z27YbCuL}ICh+i%E)e^rx@aq%$t)t%%`dR7vRZjbPAKXydR<6n-SPg>JM6f0VYled5 zRIm;N>x6=-Uzv;(Yzx7*B3KoIRYkBi1Z#_6UkLUM1uaeVVareoTImW_Ned=tU={JJ z4!`Q+R||f%%#Zh4>VmCq$d>wH$vC!lU~4CA)xcIw*y@0-j=zSP) zs{^sRAl3z9-2gGTDIH7LAB6owLg%*-hLg}rm#`WLs|jIE5Y`mJIv}iLgu$6iE!~gn z!?J#8nfiUmILr31Y%i8IU|B;f>%p>KYC@W2yygIC4hS_z)yIS!K}{=N&FX1QuYdBm zTwOeC!Lycl)`e%?(6hFBegw~tLeJDMJ;r%Mb$Y!M*t0vfL3R@kp)e*M(V5=`|4Z+qhWJ~=PV;oy2uyqo)+F+|K zYz@HHK-dO@ZE(m|yf*gN(PXpIWvi8D^9CgM*IEKs7jSh2?jyi`WN^XyS5NoXMi6Wi z3Z{NXF;1{E1Urjh9SGJD!G;iQD1t*EI3yIT$=@m&LqRKD!P;rTO74tx1?VFHeI!7Q0Mtl;J^|1t0g&yi!AWtoSeR~r=_W8A z1Lk9a84j4?Ad<=$ukTeBJ zQz01*lF=c_Pb8U45-VMjh9GGuBp-w1V_yUDPFNnp^cTUO(WPe5}Qw8^NH9rg-z4YrjgpTfK7|grhDwX=>wZS zV$&Qp&BbOcY{rH*571^RZLD-{8pEcs*nA3`PsOGgY?_%3k1H)f(lR8e`eNL4=?jv+ zLec^xEretoNXCUE>p#Mwcp6EpbT|3qG>KO>dE@hAL1_Y%CW6u&D9r_>6;N7*D1Pib z=?9d4g3=NwEd^yfP{xNSQ~0Y6(}`lGi}FbtC3$}GiI6k}NmC(d0g@I*609%HbRTLB zo7SOC<=6?+A2$8PrWI^jiOmGqObBh9UvHQ}8!KI#Phs<^*ffJpGqGt2o0g$XbG2y$ zn>L}%JF)X-0Bi<`P1C&5XZlU^x}jRbuC>@rgx$o@u2Ey`Y%^(RrTd?0lD6|kCNBt@ zh+cE(H5a{B&}(IST!GpGt!;?*;LC9<&_JLK6treQYbI!IfYwIPCIM|yi1rqL?qU|v ztaKwaO`|1u#->8n0%R?OtTo753t2mmwF}8|+lvQ!mOKb#gM_R($eIgTTadLCvdJKu z9FjS|5Hg!&R=Q-(K-NsiT7s;lkhK9>8zT$WuU5K`eg?bGLc7W};_L>)Zm`(3gH1cJ znF5S%*))(%3&~z;jzxbS$*goEwFFs9A!`G&HbV9p$UYOY zjv(t8l5Or1H_L{BY?zR>23cz%>j1J2LN*;_(?havNj9HkR=Q-ZK-Nmg+JmIMkaPk` zr;y~b*W*ZrgJignv;j#QA?XN`jzTg6Br`&i2CXrR7LdeBm!vgFS_?@#%%XNOi#mX; zgOGIwS?7@KxV;dpN5K&w8zE$ELDp8tI)SW{kj(_y%#iFser5eal3D4JwMmnC6O$`_ z8$tUFXrBpMN1$~Sv@SsF5~3Ba7>70zXd?x!9njhdT4$hj7PMJFn-!w9BHALNS?Qv+ z%|d%5`SlcS1+6{M+6!7Ipmh?ou0ZP=qUDKQ;zt2(l%RbEw9f>s3(&d<+H9cB4$+(+ zM_5cWD_yj9S!h#|Gp(JVbpToiLF){(&VtqrXx&1z;Ahcw_Z$th(Sp_U7kl zoiI;2$vo)+vK~SlrlkjzS#tP{vO30YT=brrH6AnPGyy+PJHB%5yE zUZ`XfKsG_hx`3>Uko5vtFCkk9vV|ep*Cbm>GAmuO&LHb7WZgj4O~`tJtf!Fm0a>4r zY**|on+URrLe?83y@g~ENEU@8&hOByB8inQNf(fG5t8m8=`JL_K+;P{`huiyNOGsW zdZ4pt5=bTqNjJ=*ZZeDdfUJ*@Ee6@*kgOelx@R@XtaQn`rpdfn$pd{?LF)mu9)i{z zXuSokAJF=RXtm#rLz@h=$%57$Xx#;^FVOl5+7h5G3DKNis98faD_yj1X|&`qv73jSbrLe?K-{X?=u=Qy${Ae$m&JwVn&$ohe-pO7sD+0u~gF8(^rT9R4ml641J zcOmNqvR*>g7i4{fYyijxgk;5IAJ$9-*;FCx39_C-)*od3g=`tfmW5=stbLJhNLoiS zD_yc4AnPGyy+PJn$ohe-pO6g%*}#yjM(pE=X&{>>WW7MvOUMR*Y=Dq02ifwFtdHF% zi;%4+nUyYCPmuK#vOXZ|BV_$S)?dg5foxDnb}II!@pO<)7qZ?U>n&shK{imxR)B0p zNLH^a$TpD7N|&q`$a)D`Uy$_`vH>6)AY_9XleS~Zf$OZ}7 zN|3D#$r|?r*+!CC>5}yZS#Kfh2eN)bHV|Y3g=`4OhJ<8i*%$HaX~s;D%@ne}AnPk+ zgF!Y}$X0=DRY>Oi+|=hJv(hE&1F}9s)*od3g=`SW1_{|vkPQvV`ou2(vp_aW$ohe- zpO6g!*$^RH4YJiC*=xNp%QlhBN|&rJ$odM|0FVt3vcVu5EM&t#HY_Cj&^}zNvurlV zW(!$=ko6a`p&%P7WNSdSCM4TSvdtv3(k1H$vVKA~5M%>|YzWAP2-$Fu4G+ok#=iA1 z2V`@EYyijx2-z@@4HL4pAX^)fIX`E%g=AK`Wc@+bU&sc5Y>HX3B3h3s>XeV!uopSsqA*-n~S>6#6J*$^=s z4zuB6HVS5=#B40g#)f9S?5ni(EMpPO7Kzy~m<I6W@BMCR?IfTY;$O~y#(jkZkk!? znhk^5Ffkhmvyoyp24-W#Y&^`yhh|6Z!wWjkmcVR@n2mth2r(N6vvFd!1!h~qW~ECu9Av|VY!t{w3E5bXjTN#9Ae#`9WskkgTne(KLN*d)BZX`{$i@rVR*-EC z$u4*RWP3?wrAsyfWFv%ZG{{B^**K7m6S9dQn;4R_)?G zwAf9A-9)k54!iB)s`lhdT-Ejy&q^0>6!1m~-dNy`6}$<+n-JoSR=ml;n;ha@9QzPu z1@Kk~-X!2m5}X~t*%9JwdYd>0h-0OTGa5Lf1!o*^#tF_u;7km0#wgAd;7kc{awYCc z*m|pL|4QJj6r8b`Sz~2pO$Od%!P^PEogv;<`5TBk zfOm}WjtB2};hhBDNg?kz<(&%NscGKW-*H+6-c`ao4!q-pcM5o?2=6ZN?g|&Zhk2!t zow`;!cK#viTIr1N#zJ?j=uUv{1ks%g-N~lQcd4fVby^xV_IIFG19i2ajtA;^L7fWJ zse-y2sJlbdjzsl{YNZp&KTK3Boe|zRppFyNi9nqws8fJCMNp>$b$S{#_LrpA0CkO^ zP5|lzL7fKFX)dbo)5}Un!#_eVE1ePEczBH$uSxKlBwkbDHC4Q3z-vazt5p2YOs$32 zTJf3)uZiL{9bVJL>kN8X>1g;z>1Cxe!kYlE3F0*wUX#UZ8oZ{7*GzcLOna4#JJ76y z*E;c<1g}ZrH3MEV#488AtaLQ|WAw7p8R1QY*F^D}4v*>LF$*5E(jIrld8~)WdhwVH zkICXO6CN|gBPTtqbkh3A>0zZa!kYw-N#ZdT^Jl8epBeC)AzriLH9PGU`^!}u;I%=# zX2D~Yc;upol}=j!1U;;DMtGCqG1)xqJ1XqkLyP9EUAIQLTK|2+-Za2W6PTHRnJF-H z05c~IQz~vEZ3N6lftiYlG*u?jY{1PHxZH%Z(qZvW63$9zgf|6nQ&MnVc{>Rdy6K>s zE_Aa%H%sW|f^Ke_F7{WjJ_p_BLN^U`(}Zpg=;jDr9@1Iq!1$*~XQea3n+m$ADLVVU zOM#mKxETUB8*sA)ZXV#~rQu?)8a4rLlfcad%v^!VOBgGi*!~xUvC)gfxxf zXl7$~nk~E2JkZS(x`m)yn5K(8_udM+twJ{obhCtR0q7P8-I=7b(t+{6BAu1a2yZ6n zW`=Z4rpqnRj3qiL~=$3$PNs8{yOmsUyw?pU_gJ!YN z6e5k4PH_KQ(pc$?@aBMKj?wUr%6y2-7m-B}StKG$A+j_ja#tpioe5TB^LS(LpEP%)Y5m^k8#Uio{BFj=Dr80@^g2*lrnUCFTK6kJD32!OH zmWtTf6tmLt@V}>+mCgun9>nH}*g}Xc6tN``TOwl1A+|gvc6TPR-4NR?VhbR)fMVGa z-ZF?S6S2Y+v(oYKf1sF^&IoTl#O90GQiv=SkrfbGkrFALNn{U1_K3(rh%6M5k1E+VTSvMMEVZzhp_5ZNapiy^XDL{>s%rHGtI z5i6a%{?8P#(i!0`g2*BfS&BKdROZkMh^-K@)eu{q61y*x*nWuZ7qKM}TOwksAht@x z&Zn4_j)(sX#jJEjc#9#nSj3h=Y?+9ygxE?ETLZB*fmrTD$;2I*%nrcpfS4_X*-|lE z4YSo^b^*<-bVU4LX=bG}!dn8fC1SQ5X3NEF70gzN*;<&bO`Byr0Y3<{gJQM}X3NBE z4b0Yv*@ZN-(h>20qnVY?2yZFOmWtU5n5_`A)i7HvX6sLjd*tz0HhSz5Cx`JL-IvReqVtoIsm^;E-3$L}}wE z*JgNa7O!pa+7^0^jrIBhUSEjU26%0tSAm4L6<%A#s~EkkbToXAURF9Iy!G%}FJ7O+ z>vQqi0%8TD-QwW1DzfNe?TXw7yRdE1ePE26$``k4^B{BpzGg zu~j^Fz+*?~F(KCDOL%-K9^2uuT|BO$hm}rR{|tIq>5T9;!egU&Y=*~X@z@5BZQ`*L z9y>#iNwFSZ!Q(6O*o6IQ6Za>(PrCzNJH+d1dRggc_&Mlhr8C0&9A2M`*A{qf5wGp= z+AdzZ;I%9CniA{vHN3tSubuGNDIV9*!%8QupOYR|x+AjrJi__z2yYX_Hi_6)h;0?I z9T3|gV!I)>I~1E1EA|bV5~^??iVGboYpEcIakL>sCu% zO*y*7scWSph>QbjGvdfR=Ok3pstn92yYv7w~6i^=dlMQ`vH1C zh~7Tv?K8dL18Mt<%dgG*VDtmV+zDF(60y_t20~itAo%$RX{9?N2O+I=MtIu+xm_T4 zVVdreX}TBCdj1(Ak!rKAg9pbwizPrVDAAI+T??Lz;41E{H`u+sppTze7d=H3k4*2FsEd$=C*%PU+ z=yaCZo9Jt$W8m-<{&S2flm6cRzghi|--$9twSz#QOdW-=D?z zAbbysZ%+8;O!tDqB5UdZm*8VN@v(m}#7o?w+?ub0}v(g#i?S|j(EWcc_ ze*56JPy7zT@1Xb{f!~qPZ)L3Cukia-{0_tKu=w3dKP#Q=ej)l<>5j-tKP#OP-X8ev z$@0q^>$e|%`^E1N{0^C4aG-9iA3!|{$fF_T>R8C%0Qs9h9s%SLfxL~7Ryqj&S%kFG z9g&ZaRyrfRy@1@C1$k{Oe6Ab%IgqkudrkR=Fd zrGwy~O-L)<5%~#er8C0Y2grR{kbW%WK|mf9$RmI}5<+%S$m4)K9zw2*h5Q4Me+c9; zKpqpw+X-oGs4>s$o*N6`C=gt0rHSQ9tGsl5VEU6o&e;D5ORGi z z|NbPzPKII|V#WS~*k2-cC~x#8$f3OMf9nK9Pl#wqidyOX1^--%TIr4`NKq@D5#B+F z9u(0d5IrKI$02%LL{CBVR4BSJR`hR({w<=1A$nLuPeSyhh~7z2D;*90Jc?TBjwnP? zE1ePEA&4F_(coeChjE{6ISSmPf_nnECj|Ek;C>O}ejbba4{-kx+#|p}BDkl3drENc zBCeGVjDJ3Ht#n76MO-VL5#C|o9!}u~m%Q$WW{-jPn9!aC?Mb0M4cgNo?Uq>De?j}N z&>jWtQK9_;v|k8qDbiZ$u=p2{)=GE8*`&478Q~oP?U59%{iw3g9tZ7lp*;oKQ$qVC zXuk|;x5v_E8x~zevkh}M`ZVZH3*FtMv(ots{)MEo(j8HlbXGbeyrZBynxeB`dlkA9 zpgSRSUx4llq5BGSUxjqLV(GGjF1yfu3A!(Zt~BYabYlA#k*vRMNbq@VBbC=`}S8*{>oMM3gbRV z;qX3Fog4|TUXGai4*ostij|J2UxZz;(j9RwyJDp?!aI(x9Jj6*PUJl66k2ggTJa@X z@nzVGY1)c!(28%uRvd_Jg^yPF(u$L4#Yt(!*J#Dp(u#A?igO~ZC>Ps`d)W#r9VY)` zw!%tx#CdFmmCgw71X^)ITJZ&1@rAVFE41RPuocs_72l#2--fL?7~6_7(26sp6{paO zQ__lW(28%Q73ZQA=SEslIkpw|u@zQ2jQ%BTg_Z7z^Vte3oe|ziwBn?+;xt-uT3Ycn zTJd$*iW%C9@6d|x!d4uLZAA{WB8Rl%3$)@3X~nl_#kbOm^U#X(!d85eae=y@t+3Kz z^e<&AtaL|Qz*bo4jPOpO6{n;XU!oOXN-MrWE55N-aDn?C9r!-%z~R^qR(1EX{ z1K*+p-%1C5KnH#ZJ8&en1G&(FT+)Fr(Sa|e1K*4-ox9M1O|p&!On4Skb%?%`2kcK=d0C z{RyH!iRdE~wbIe>i&4}{cf=(WwbB{keGSpCMf5v}ekYispl8 zJ`w#EqTh<>&k+4tL?5N7m5zpgB}J`tM_fu#E1ePEHxT_sM8AjV_agceM1K;|Um^Ny zD0(_pG(SZ1i|8*9`^6RWF2S+?lJMBS+s?kG+p+(@D>DBv(pu@T_*aqEN@s-kE#STt zxE}!bgTVa^xSs{?H^BWC!hIPFcP8M@6u9p(6~C9M_$y$471&Dwd#S>dt5>V@-zRi`hwblT`y_3xbX@#vX=|lB zq9|>xbVhhT!1f2R{Ta4Di|uc){Y`BDgzcZ9?YFVEg7~4N!`-j** zMO!N!7ymliTIr4`Mq4YL5#Eom{ZVXxf$cA1`#WrZ7u&yJ`&VfDU99a{usus`i^8^O zXuCDW_D|UUDYj43)=J04FHT!4oe|zoko!sGeudnxBKHU6{t&spA@_GE_kFC~*^oP1 z16e9q=uEw2=7;D{3;rMK;sY5_!}C3i$=B*cp6y3 zj+1$U&ygp*&Gzpv`?oqdr`*rrp9{rvMe%AVUL7j#k5T*=ivNn@^Hj9bG4gMsqLt1F z?>8v^CW?PT@lR3w2a5lQVsQbr90wgDq87`@P3El@1pn@6#o*%f1&uVD0)!zB8oqn;2!&z`hEj4#n)E_#zdpbd3C4sA#1#!utb?e~9AWQ2bjIvlT<9i@AT_hoT=S=1%R= z!QPy@G;{?ofZzopcpU_;c&muS4xe9wz*agVyuShbw*Y4=j7d<~{lE7C z>0zdhu%wP||o&e_na1H@}mB3ay@%`Hg zY^5{8`v<`P2yk`)XBXfz0DOi3=K^r9061^L8*R9A?B68&7c94HVwZ}G0e!JR-w5a% zBhb!F_5tk+bWT9$6zJCoZKcEL-$7_Aoe|!@fc{sYJwST`odeK01UfgMa|h6Nh8jQz zz~hqtf81=o1jv^N@=ZX#DMa3+H{Y`7i|&fq^SJy;kQ*JyEgiU%9k3F9c4zulcECz!gqIy1$gUkY z106U+I*h~xJ){53p#L1qyzKW0UsUkr2{$9ft=QX z;N&Jpk%V_g5uDuQK`Zh|EAC<|taPCL+t>;#oe`dgR(RTq9B4%jX+>_dBDb_6A6k(w zY(=mX1!pj+$5w7DE=MaamsZ@0R@@r4VzVtrPAhVOI+slLyb#VS!lfu|rQ_$9psgkce5Q<0@K!>+u05)oe|y{XvZ1aj$CL*E@?+z zv?H&y<4m;U%t$-FPEPpXSR8i@E{b*(m3EXsJ4%G@*sATwiFV|acH}`j^2kn+A6>{V zT`0{iSm_x1cd!dqIwQOs=t2(dLT+>+w{#&Nx{y!0Pyk&h5Ol$g!Q-t1K^K0E?LaYf zpqO;vc68wOumjt)1G&(FT+)HO=s@0ZhsdKl#F=QtnbL}T*a|BhXul*|VWl&|K42a_ z9kP#`yX#XPv?7nRB0pM@Us_QRttc32MQ}QldfD1N0$hn!Tq&)%1Fg6tY{hnMMQ*er zx3nT3T9Hq7h63n70qMZK?0}WC~dfpZLkuE z)`q*-1}mKrUT(A@x3(c4+K^A$PylTxAZ<7cZ8$635rQ@Zcgy0B3Rj~QS4%7MLO8Do zp9$eJWqua|Y$1VtpI5zBI&A*^q_@%?QHu0dIwQP1pwFZ9`9Ysw=nI0rpwOQU`m+Oi zJ4c#e?8oij>5Tl>fd3ldzYBZ9UE!XvOZS9)=uz9O2bN_VWq-`1#h%Dmk#;Su>8`nf@oMl*|E+>pU##(eZW3h2}4`49%P@abVrnC zpR9C7c=^yL`@p~3rvm6x0qN6O=+jx!r*qJ!bAmqEp(WU{Qtu+U2lngGpX;PQccVXd zhyB^3{V4?hLgHT-{)NT=L;70@8}omN{#Lpp?xDYx&Im6*{PU}SLHHLG|FhwLw)me5 z|8oO>yS19~51ziHE&}84coau3ic2p_qZg&aUhLIgoP}PTCA~NYy*NjDQI@^1(sA@3 zW-qLCN8HO^Sm})L&O|TH)Ls-qFA7O73ZoZ=r5ER+7v}}N$oF3_4ky>F;9@+}lf~=N zkL#r$_n;s5g#Fm3{V0gFtDvl1XQN+dTfc&x_AEWvoQuYtD~&71##!m0`;V}3R=OkZ zW8%y{coCo6b zgt$D3t#o+&M@ej@JK}y4Tj`AO3WB(x5}%EI<80YC&P5B(l@?rp7F-atz^=#t|Mlrc z(BCNZ_hEmyFWesv=>BjHdT@^P;C%GpeCa_2_P|QV&wq?Pu+kmz0DEAiGr}u`9u(3Z z6h;pUOApRN56+VwT!NS{Hf8+Aii0M zAHZ~fAe`=pbh;PDl2kaKt8gBAb)NLwVpij3*pB_Y?9t`_* zSo?Gi`gD%;>3sC*eCg9g=+i~gr%LRTm5#ChB>QBgJK|yX$x3I0R~UUNtbMu=eYjBi za54IDanJ`lG)xJ55dXOJR`lRj>A|_6Jy&Qi0PO`XtzVgRRywi$r$}d|JK_=2S?P@M z&H>#yN_P?HE)u#+KzB(3uGB7f*ur+9$bnZTpH;?u!QW7 zy}?=nJt!ePcmzFoB<#U4?ZNrz!THjIi_n9Mqz6^m11lXr{~7kcN_WI#?17ce2=6@f z;5?@X`x4%T=)r~3gNxCFi=_vbp$C@*J+P&GhWQ7F+tlGV?wQ-|=)>*OhYP@af$$aq zZxP|GMqVo&8vj}HTIr5>oV->#BfRs$d%p5s1m25;_Y&}4BD|M__ws<(ZZZVCsW%W) zN6Yw|40nL|4k3OFQ~j}Us-MuQej$2sq4eTn^x|UaMRoSVO2^TEj=iwb9q|NvVWl&| zy8ykoKzmUHy(l8RxD>s(RC;j*dT~WK)n{2Rg1gv3KjL4xEr~vqls-I;K0F@w;iUHA zBJ|-R>BA-H!zFGXyvwhTK5xAIdPmT&!9H2(j(DDZveF&#B>QBgGs3$NeY#NlbTRsL zvGnOO^yxC`Q&IG(XwWA+tC^Rz&%`Z9ccMpkN{^mEkDds7bV_?v1U)JuJ-QSR~} z1$uOa^r$9#WToTlzrY?@>5h1cJ+jgn;a!9tUF7u04&9faN0&&CE=P|pmmU>EkBT`x zS{-}nz6(9NOM3Jqdh}%2qu|wb=K;gT=+VW}qs!2v%cMs|(W9c$qZio$D_!3r@Gau_ z?n-!qvOni&Nx2X7D1>dUzU%QXH%GQ|FPye{5{&&OnZn1qD zwoiw)!CMt`_=@ADu)S1luYm0puC4zv?W}a|E`i-8YIiy8E*HCEuq!5ZSHte=&~A;{ z#eeLlH0(-?-7~OzCbSFQNnAv`%V2kz*cF9cQL%f4c2>G}m%{E+wYvg#SBTw}u)9+1 zu7TY(pjFDFr`l+CnV;X>2fzEo?|Jw=ANmC!ZP;h~t^GhW ze{07p3dW+scoi7062{lbXr;?|1sJbz7}qAeE5UfBFkS=3YlN{l7>kFDpBrOvwVe79 z7H4!F&;zFGex*mQPeGQ{_L& zDu7>2*B6%GouQSPDYD8Z|u@7?I0L~l2Ihp2+ zpOX)Q@j+pH35+j=jEyqP$*UlFl}KI-$!kUOf0VS+mAn#?SE}SSki14Di$k(_C~2RE zjeaEdMo8WmNZP%yO}1wT_ancufAJ?c4?*)G(R>-2FGn@qNqIFWuNKPdKzW@|zC}ta zUCOIKd6iOL3(9MS@_JBSZ?1IIL=0br;j2-@d{xVp1>vo>5)j&zUO<@o(P8&+{V4bz6~5QN_gcvJNrt8I1_0e4K<^UBN*Cx_09~s<*8}K! z0lEo5Hwn0ROu4Qpp7FWv~VR@ri-U7>8#Igh|O9Ym7{0%IJ*}vcz9Dh>y1RS3b z$2Z~lX4Fwuyc@uHgD~C<#+!w)3>mF-8LtQ9^~!h?7;h5BTfum%Fy0Qv+rufj!}x-! z7(DM7W&h%L?k7R{q)`43l>ZAUn`Bu1ZUp9yf_V!tZxPH7h-syZc>^$SP|TZwd9z^N z2F%+8^A2F%5n$R8IGB^cM?~Xq+B^lsrv&jWAifnvbXUlmAb67q-U`86MesukTImYj z2*Ddw@D>Q(B7!9#SV9C#La<~w9e0^ta1OJ`{snt>{B(R8l241|+mL)aDyb{v&9J;# zEN_G5ZDLuLmR7o!H^K5IwY(LUw~FQMu)JL??}X)@fu)_y1m9Ve`mt*FWab(8JtKba z!0(-?pRA0xfbSOJD*?U|!dH%bR=RvQgYRbLyA6D|3Ev&yyF>Wy0^eN$pY6;6U+^)q z)Nh2jgwKNTSs{EEgztug4Ku8Ww*%>RBIQr`<%wjai*yT+Zc(HXKq?_fC4p2@kV*lm zREQMpufdy9@%Iy+1JZMX^d6Ajiz2xz-ffs>x5+fS1A_Lw54`;JD^So%XM}ev1aDQr z+aY+n2;K?7J4Ntr2;Lo;X2DAa@vr4Q55ea}@O=or9~IPmK4K^G_=w+ zybXr8so@_M#yq$=4FZ50r-YJH6!|-k~ycdS|28MRYvETfH8~VZS8h^?05*%L= z#}DE7VbsxG@Ja%)q#%|8VktqaOhhYP#5;g^halbs#JdEsG!RP*;(b88FPw<`3@8*6NGmP;oTs-TL`O=&`OuEBnV3iVJQ%n62f~xc#ja?55oHc zLOZeBo1BAj?>oH$zE^~=9Qevb`DCfP3wn2nUTNr+Hoaim?v~HI`BlkirOS9H81EFu zyTN$3Fy0Hsdxh}?A`vu}5Ks@9?#9#Wq4v5zUq9PzFMj>=ryAKrixpT$4 z8v=K$z`YQ-R|Fn_zyl)iFa#bB1nlT|z@|d_AseQv7|5Hv#mf0967|r4VR%hBfD2 z5Zy~6dqVsGh#oMaU;)2Rcd2_|b&p!z53Bpd>LFM?Bvy~Y>d}Z*aBDL4`{(Wj`2S$_ zKe4I|tIAO;cWt>3Q1=PcgMfN4gt}j$?giAn4wQW}-2;GnK%gE5)WZVx7@!`DKn15% zlVZ>9-vZQI0#yZ2RiaS3_S_Gu`-SQuP(5T+dk55ns~@p=Sa zk8olYussV*4;WMMPE0oczc)F8Z-#srRu7BSW3YNmte%9`lYx~jnSoXO_inxmqj$xq zI*h7Ejod}*ApkujK#v0GQ3Ba&{~&-K41uycK#u_E5dnG}K#vR1QviA@0J7aL1@zxL zGx0~i_ki`DVATLtjVP8bR1bseVc~iVT#pIYL*RPIxFQQ#FqIyK)T1Kx1f-r2siz_J zbU2lQ?=*@33c2^8^S8E#H58gdK98hSbv{^*E#+ccko6{V7O2B~s5q>RFL`0a7o7QYUO41@9cj zuP)^vRZgVpL8@LT)jZScf{0IO#HSJQX^Hq8B0eV(Uqr+ggNU|>2A^CFE}b$j8s!nQ zyu_@JnDwJEWzj&!CpF_U$oPz8d>$E}my9nV<4ZwCn{YwKFJiBFDj-`0$@USleH6{6 z%fZu_?N3K$yIm;eiTrZTQ($ z@vC408VS*82#toJMym|__OtMK);uDILc1h+p-A*|*)J5q|K66zXTbD~GCdEb=Y{Dd zFuf#9uY&2-fXVio;Dz=0Zx*Noo=U>g2t19VJnowCBC@|I*`G!BXPxY}^uK`YFG%*6 zk^N=K{u;8s7G$>zksy2O>0QE`n*5*R?gLbYLuGMj42Q;12VFm2g2YQA@f;+cQ;8QL z@uEn)0*O~d;&n*89!S`-@vWs#9Uw?pqI99qi zF9YXg2gi;-uL0*Z!FdxnZwk)az zpPlzReE$RA|Aem<`K)yR!fW7rP5Isg-D33d}-hs_Ku8rT8*{yW5zlrQ`I@#@j_#U#qC)qzh_78&Wxf3Nb zpJ>-d`udW-4bry>)3?bmIo<`py8_UT09LvH{{z7P6ySXTye|MB0^q|mK*m$)j{xwI z0JH@_+bDqB{aG`&N-I28yW1{z{-UHKn!t@!LtaO>)0@GU#lPxi2z*I(< z%7UqEnknO1bptRp5TrxV`$;CY`s_6I(M&WEB?9y;aIIvLNw8$qX$=(LAU`%tG#hKcqbCfa*)qVxd( zKM=r<1hmoxd>4T4DqtA^mJz_R04ytj6#!Tv4VdvPy)ghA3t$HTc8CJH)9Zccy)Swn zLhnP->qI>(UA_09_nxC?d*=tx`#|){L9d+XRfJx}v|h&Z^pBzUvFLS#UdK>xOor)K z27qM*uq*(}3SegfTImA555V^wK-+&m1mK4PSRR1o1uy}?L>e&TnffOH{6qjd0kBgP z(4Btepi@qCx=_bTSEmeg%BW6R=#&+m3ec$_I+dVPDXo+7T>Mk$d@4Gfq0>34qc^9@ z!>7FXbfu4#uFnVX`M~k9-LD*c%85@!_*4|1%J8Y2_Q`lM-UL2P#HR~jA$WQ9oI|DuS<~ z@Kpw1W%Ai&i{FcWR=R!_;8#KYD#5Rk_*I2pRq?9;n!09dcv<~=r=9H z@|J*LLIkTou!_@!O9SvcWr>zM)3LouTK#T|Lm%OVQO$RE(qh40N9fU4PK^kJ9OyR~>lO1+NzHY6+fK4K&r1rY2}= z3QZl*)DfEcpsAmtNhE5;(Xdd@dt5QS?Nxz>aeS> zcC}zvOYG{xuCCa91iOy{yWDmtt(C|=HIAyS5 z4_*(ZpOvm(ZSd3PZix6;jC7uoAd z_K%SLBgx(f*&C&@d$r$9c!fTQYkX(q?=1O;ApekPez)=U5x%~JAI9)jy5Z{~d_4)@ z0O1=*_{Ip|I1GPd`GnX0mALR-5Wb6qABylpqv7>%^AX~IB=LtczLjqLI)3!IUmf4( zZBBbfz{8W;`Y@_5Mh#)qP>eo?(Z`|DHE-H|`O0xdU18K!jE2EzSky?4I}Je8K!`?= z$V!)}E{N(HQRLNnd-nGcbUqTDM$l;_I-fx2lTfFC&7gTz;&i$}r<>>uhtBX&XK{w* zqal16iqA;;Sn1|(fcy<4e`DltEcri0{!fGa_5q6G6%$^;_Y&Sk&)e5PG>CKP4u|gI zFai!Eq7Lpd(g+BR1Yr~rtaK3?0->QGd<=w-1)&KLnxrN{-Na*Y!FwQh4+%aJ!AFL{ zmt>d#jgh^vWFO7!R=U|6A$udq{t2>wBH5cFd(%|*+VRxF2&B-&_18y$@%M+Sc^!&&KuYv@N;{)T?? zjOD82$7o|diqHg6n@H5=h}t|AwN`x4-U!-Tf{sDZG0~vz^6rmgPAlDzDU!?wu1E-b#1VKS_sAesKE}i*Dy-58$k< zDbhEU^evFSg`{td^sQ6rpNUW3AL;u``UyxsA(~!x*+~phZuXYQ-cqu+LH0J1{WE0$ES0@>eD=Y} zK3K9(LG~%p>`v4DX$)qi8>|(AwUS_M5v;8QYmZ>_+XlJYNbb*&`!mVi5xG02a@R`4rXGgW!z6WUq;4&# zXEL>wZt7M@-71yZ>k|2D9dEo}I$y$qw?*)_61+Wvx0m3Z5WG_=c#Zhr!x4PA1aE`j zZ6x?C2Dj1;-WtJM2f=eDvd_Y)Mmr>KCy6^CaR*7<8Hqcm5xG;Y-%fy5&uaa$yA zD~V?_v6XJ(Hb~qiNNk@_=n-x8gs|10A^2w!yd#2ll;B+uyh{)~w;ii9L?4OhBPDt} zL~ke2=P5t!S;@k?VZoV1uHqSRb~c6QXsJXk8Jl zt3>O8Xgz{xwlCYMgID;9xYcDW!i{yqc^$Efb(CFf0mEDAhVP6-oh4B>BbXjZz>IwM-=FxuKkv}~!9oo)!$O@j4Au$~gE4}$ec1*;tYzQIJqn&`&z zx}u|9rK3w2+e$Zf7sT#jvBO(|-juMB-I2GuMD(5#y$_=Ik?8#qy?-itt@z+m5PXUR z?}6Yw+*W(tk*0ej&Gax$FQn-uY5F2fUr93nX$GXyRE$qE6=|kw8feXzBCWNZ6lYx~RA4#L(B z3br=4y*8BT#i8lg;OVl#y|BT(A{#s_+~5J&paHT$gRwz_QyXN>&hRGF3~bO0*`Pj{ zy?xx->#yeCYNflk_C}=Mkw~+{NCOdRphOyiNJCOHB2%E52sBdy^+lk*5@-zrS?LDq zgFt;Ef#!sP1|iTO2{aUehNgOCQ#?bDW+BonHo z$-}V8!y@xM_6@Mv*yP#nCVTzSh5piob&O=C8>t^6^@~KB7e*R_NJAvja6}p&*;8U8 z%|WC&ZX|y_H`z*ellx7u# zEb@#E@&xxZGkh9r5fUwO6M4h1vkjA-Z3`1y=_Ve5JR>B}Xyh3!dB!2nxKy5(GUZu} zJc}jIaO4>-dA2f-m2RG4esnb)=4buyy=7qsM znJ8?7!nUY_^N83RiGU*`0au0r#~|Ps2{;}B$4kIT2skMSm@gVI!|`D`GA@^l+mUg5 zG^4z=q^e#+ktt?SFcv5blya`432@)n26GvP-#4r#*5Mf|f{es&^QnM4R)B6JYO0%5En1b6s?$8@>FpRn=P zh8h!~F+nsYLu0aNOoPU>lt!(1i`B4LEf%|Bu{*R_89!%yj~rGeIi66Cao`vias*FT zvN+a-923DYQ8=c6V~TK02gmdjN8R|(ldb{B8sXRjjy+KhcWU^wurg`!q*{zmTX?OK zFMN&5v}Ranl4(ipfxL{RV&_VJ*?J? z)qYs*53TBFm|T;=HCecFlFP~@*E7mBDT}LJl50}PHAlIof@`X9%>dU7;hGJu*(t6X z@mw3gwL!QJfa^fWwJrnK6mU%uu3Y4@GRgI!o@5<;i!^3k*0%ax)9|h zk(EiJ7nEpP7Lh&MH6nYe>k!QZ(M%zl1EM)XG#^CsQ$)d0FLo+z2GV9hIs&94A<~)* zQ)vdAW{6WhI$4=?dQqLGXF1tZV{@|S#g5Y~IL#8Lxp0~*P7C0)AmvmmUTF)IwusVE zC>@O|xl?H-h-L~=eiB)kBzj4SW@HiBqiQ3vhtv+yY!J;BqIn>iCqxTDv@k_fBc5n0 zh_(vRF%TUKi8f`JNVA|cOO(!}l9frNmsM$ImXbXpHzj*G?kLTH(i~Bm52g8{vhbrQ=a0cOuOO(QF|qKq4!XM8U`Vos-O2Sw!|w-iYjRyhAh>M015` z0f-g|(P9uSPERDy?k2<>-nIj2yC9ta(upXN-u{{cra8h?kW5x4nO;?<*;!2Xpx>D6 z5x>JU4@~ofX(5;v3eyrWElJO$3`{$~v_qIqg6U+G$-PzP7ovidNrl%`VNRBUy&Yf* z_FjOaFdqu@MPU&X7Ky@AC@c*W^4LA`682E7MBH@Q35T8Ha0(8mLWd`Vl}DzFe-`HS`=ZS(#)CzHiVu)GWwivNtM>$=;=Km==R+u`n$I(=uUN z38s|+Q=Y^V$>&KKKCHACSbGKQD`0&U!P*`_ZM;SBS|ncQ(#y)ES8!X(@miSWWv^qH zm%WJLcrAg~67gCNujS&k3SO%MuiWNUCw{Hn2djNz^);-%cCFlrwHQ!~1?oIPS($_i zu4EjjMOjexj)y_n+Z_(nQa~*gs1<-(AyBIUwK{+bzL7Nc8wd7-X}>Ui1Ey~xOiyH( zQcEDUM5NBAl$A-TcT{R|mXy6VVp8_Ph$FQOQp-eYC8So0)EY>wNl87E_{6qFZe<*R z)B%zD7E<53QtpIW3Z|vPbOD*HOftQzOiQwu>}?cdviDFNrsZH-E=;Syv`U!Pf@y7v zscQUJ+#UqeL1Fq1Oy5PAGCUykFQkN(Ns0GVVriCyz13k7OGRP@Bvy#TYDlaWiFJ@z zmy&ok5uAg|ggFF>Ln84#B))egoC)J!LKNDJ#guWU?~J6nsgmb4Xf|#boc! z7?Zs<<1noT(`sQ_2c~txv=K}j(@ep=B4IiTrlZ326PSLAFlBlsxC&CMMCuYsS(%gy zPFNkOm040FlTs^1Y7L~;h}3#Wtrw}!A@zAmszxIA8`_RR>X=CV45^=8DR)Ax2GeR` zx|B>-CYdTJ)2b{cdrQYAl)azhOsKVBS}RN&z_dY_Hi2nVim7J&=TnY@>9{cc0;XRg zOc`$a`Ik|`%A`bPl~|o6F*+%+S|rv%Vx35Agv3UX*bIryX^Ggi_yi@Sl~?4a2>r|HWo6PU_$mr#2V0ZnWp~`{kF61}_3&CRUZ2D3 zbMe{&uPuRB?nF(yjEMbWjFS*MDPq4t>^E0TZrgb4V74waTcu`K(9FuDSyeIfvt7wI zq^`7){06qQS*l}`s%uR(XjSmEId}M4Q22Ck19&$G?Rh zevzr#3q?uY6{@=tx*J7zGjunL?l$OdOX=211gAct`vr8r5ZynZ`-iLR?(7>tyTNE9 zbF4tZFGf)-lcLpC)T5}C_*?c3Fzd5K+b2cWhoX!0f&b?a{ai%1Ky-_UZindhKs5O1 zV72(~GCK{^(_;E3O#gIEWjXM#q?(mUwHm7CQ_V_OZ9|q?$E4bZP%W5;*}0c*g4!lg z+X}UqrAxLk zi>y%4H*jEDfH^Bamf;qdbe>JtN zOlk$69(S~IP|HeJYYPar2*Gv`Y!`xEAlMZUS_OuW=PCY$`^e=vC0#9IDg^{O?> zL|$Ir3frw>y92g6#CA7qcL%n)ZF;?$h`q-82D0CX?7xuxH!3R+VXh^tmC2lS6gC%O zt#o0t6V}SC5&m^)*v(n6smGg}Ls)yv83Vfwu-gQ7Ct!C9>>j}G31EZ$Hh9h^`|Y=2 z{Z?4B{T2P_QMSL5e=GT1=Y|Z6-F3vZGKpJPadQ*b$}GCnsh#f;*UGFBe(^N!mNahi zO}i~2t=$)hq1_JJ?LxZ?w7Z0MFKG9sXg`Yo{i5$c`<>8c2W|EU?Tr~|i<8#MByI4} z(peDlkk-m9xRBN-t(93L{Oi-STS2=uptZBbEqbWg0oNVkx*M*$#dRNC_oZClNHmI@ zvfsn?dvW#P>P1{1&ER@HU9C*I2ER(>xaOs+m04<`>lt*lGHZl?L)vv4T(?DBookz& zaNQ}cd*Hf9T=&Cuf6Ddk__OaH;QE8O`f&9lt{JXv{2S-^k>-My(ef})CuGt>Q+KHLn^om&wb^&*n;O+(PUco&8+yen_?!;Tk$DzT= zimbIi0{BM(J_EpKM1Y@)pSboFIMLPFE*PU%IQ9!aH?jd%COv{%b4~;DvjJARe=8>& zU}e?_|E6>Uc4Rdm^#E)~*Z_MF7Sn*;Xuxi1z&n%AyV_ketlknaciejz^u@WXE+3U z+4e=jv+Z;8`8N~X$|QJjAaQ1V0fJlU{;k{uw=!#le@hyC7r=M@2kz|-Kc%%7qu z0LTvr`C*VBPLbPh6~~kR0`gykJQv7wMaXZ8Uu67SNNQ!0w6T&FB&n5IVB!9dhon|! zjqqIwVyAJC;b(qzY1w?kmin%W;)@x zm84cCNrPLC&MYlNQY#$`KQBqG%o^d}mL}bkCQU92d;SCU_J*@`KS=ir=^>CF64Ij} zJ(?o5Uo?&<{SBnQ327dX=82GII@h?3q*f+LgBK$l(z8fvWfoXCOY@P`%B&H7i8Sfn zG^uBtHcJiCnWYCndO%1IgY>YF9s}vI6zScWNPh?E??RdvqJ5+t=UNg8}d zvqO3|Nv(7&{QM-fGHZl?dzy4#nlw2}_x%Uz?GI<^L69C4(jy=}BBaMbdOSs1Iuq$1 zApJu~^MN#9NLoDe`GS8tNv%whKBlCFNor*lSU5}1B&n5IBm6tkr2EsPo^jeNHArWc z9s=nhAw3Gxqe6NDq$g6O_hcgd6Qq9%X?~FAkC0|KBk=Dasg+4m{h+yj4oR(aEc^l_ zwK8jjUouU4AWfQ_r3d~4^$v!!^e{*d3+XYC9uv}&AU&BPy*Cr-Um*QUNY4c6nGw=V zNBoi`wK7SnA6ECzC8?EJVBst+NKz}aM)-H8Ne`w;J>#@lYLLz>Jp$4rLV6se$A$D1 zNKd6m@5@B`H%R{$(gGkY5FyQU#J`iIRwhaHGw=R+B(>79@C%XD%B&IoU1`!oY0~5@ zJ@g-_cQ~A-M?rd2NKb(Dgphs#(k}wi+;%B&M<&#NfclT176fX+2x^97zL#x0E(XSD zF@$sPE}~nRMAuKw`{xtgO80M_MRY5(M);-D=!etjo`KsuHfm=c9|QU^K|cxflY)L4 z=%>@@8LzmDC90KKBm8^Q zsK?W&o`Kp-G)iYCo&xGALH!1(|Hs!o21t@@Q2?Ha98ZsJ+qP}no*vuQ+O}=mw*A(& zt#>jqA}dbZ$o;WDZf{L?oG&6#Re7_&v8b8vgd#$X1ZqV>t>~a;9P`wtg!-vK?Zv1l zHL7gmk7_b1N>3xI%%~{SS46!n>L(UeuhdU+r0P?%Qa>lu&jsqYg!-*T&3rFZh)@d& z)JlX}$)L8xF)`!9U42HVp9$37jEYjDj+G~xT8xS^B{M6v3ZtS-UlH}OsGnL?1yHP1 zPGb&0? zBdW@%DAQL&eJ$!|7FDm*&vK;dbF)&vB-Aej>i2~Dy+zG@KU9QJiwM*zgj&U*w#q(x zt1k%k3xV2~QBi8t_&x^jgOWOoiZUfLE43PQ5Fm^BqrdLM<*( zs}pK<2Q}+N^);b>El>wADoTwiA9E1ZXH=A)MpTngQKqkm23pjwEUI3qU*$;E*Jh=D zOQ_!p)Sn6UXN#Koj;I8omJp~l2(^ZTnzj3XL#W>f)PanOQlrYJCPWPw6=h0hR%$Iq zMVY=L8e~zwwx|lASgD}&R_b?z`kg@ig;0O7sG0AWN)l>Gfm)MLYZ}xJ|FQdjOQ_!p z)Ip4jQlrWzFhmU*6{V*U)n-(b=_{ha7WEs8s#oeaIa2klS*hO>>h}WmS3>>OqGrCM z$|KY~fm(}DYdNS{yZ?8D`kg=>%%~_es(hqF)QC}0retQN)?rkX=_{fk7WG?;ssM_W z3QBLK{y?Zd2-M#Q^*4)}`Hrd-p_US;wF$MhgPQRXv-+M;zZa-O7!{>Pl~0F=8Z#MSL%?+$ z;H=~84+Q*!03OP~D0N=>T#2X&1EWm&%&M)&z$nvKM8hob_bKoN8u)ty{6G-+Cj$OS z0RKV2e^}tmcUol#xQqa%~ZHL!dTMbwmmQKozbxIP1; zOkWWVx4=K7z`twY9}Mt=LEt|L@J|bv`L3!g0hSej^$4(@1DLf!eWvkIEBZc>&mf02?@fSv&171o(>p9LazvHK2TkMbv@;QKmcwun_~IOkWX=vVcEZ zK>W4o_+0+8A-shNlTE6B2=E^ZnE76)0s&SKfDH+-p#zw8-u{&Ue-(hE7!aifl#jlM zS~4KYl*a%zWnQgdf&C`HMl%>n4YpW*%+ZR$P^KIPtO34xNhLKQeB>DV|s5K*@^hO_dJDGTKQxx_&-T&lW zK>ucu6o9Z>g2sDAWkRSd5SkD|69*w{rTjq%fA|QhKuemImg$I8+m`zH8jWQpl$uFC zKO<_xOeoW>nYGj`$5b$3!cV*xsoyP=-uZCZp)Z*);$xS>g@``VruR%Wv!-&m?DR%gJGJ$Oei&ze2PZYo|#a3 z`Qm0E%Ty>~!cV*xslP0f-ogG7NQ#h@K&nni)df-uLTX`rcuDQhhi zCZ@s;QzygJk;9|(a>ZRWHhhsJJbvQ6Nc}_M|8c_aFyRYUG+WVYs9;5Z3xx=$kie-) zI5h=ME5d1IaQgkn8Y)6KMI4;Y24^y_A(VOz1s-#iV|~Chq;Skp2Ey1HFMwz z7@e6JrT5$7ju^{aEMdk^ycekgh1?+*D1={!gMXz$`Kkae8rtHqC~9n>yEb{(7T#^hyN%v(4!LnHEzgm-cBF79}D zGv3qK8>RLRJb0rkd!zIy<6au;T_W+uPrMhY!h~2@AQmIUVgj))A=VX$s*tFEh%z0ad0){X$5=99#812zsUpN! zL@*X7#^Qpp9x>Jvj1e(LV2lq#6>u0TXb(dZjAwiDZ0~qx-7Hp^mTh6NY)g`NNyoc~ z@t(onD7AOs!5`h(8>L4XH`mx@o0oXwC*F%xQSvS-yi1UG3E^Fzyz2|^LgZZt-li*6 zO*G6Mh`EDd?vIOztg~McVlE<>^N2amVeV;|XEHNN%^Y|PNDpR4nIJt1RKkp( zcrQ}Lh`E?xE=kNK1#<&pZXlQo6LVpQd6Hr7NX#7_=B$HoDPk<;F!o9qRZ*IVqW(lg zvzQsBW)3_Mq$e|@^aSH39J`uJC(QVX_aarCn2QVMJYvoh%ngaTp5{hPewd zcQMQZaFEXUBM+)9F_(3i`x@pF#9Tr!&t+zmnmOH#J z4m>HOFEgX`1mn&fyPC@<%=n4-B2|`{%L?YE#N1Rcmmua64)b)wT#A@W3FdCZ+|6Om zy5uNN%;g>C{)Rb^nDYeld}cBr0{J;Auw$1+z)nDGh2qknZ~mWd6p5LJ;<|%<2f+=01s7>JS#e$ z1I@B6P0O~lShfq<8>RLRJOX3@d!zIy-YB(q;Q1f}*&C%t8TSlX z@5+fce&W4IRV43dFts&I6^N;VV5;2EOs4+wq;f-l1bv9Hk6|46A76e{CB~`_<506& z%hPHtFIMYPW=5%*0}l}y!ptbW@y9JicC}VZnDG=6()y*0ox7Vy^Bm4>!yeiMgU+UdGHQ zHFMx$Bg2>(r6(A-9a-iY2{V4;y-2kq=5~U)0x?%`m^&Ee%EVk*FjphyYJ#~xG52?v zGcPF!v67FdYS1*)aHe5|IW{k6W|W#a@BotG%#6|#j2n?GbIpVqKk;6q+7oko!CaA; zD>}>_4RaM@t|FML6LWRJJb;)7ILw(>62x3tFxMpJnhx_w!@Po-QEKMEBS%IsGfGb| zZcVbxwGw9h#CwtIK+GKkb0uP~xFxMvL+79z*!@P=_QEKMEV@pOcGfGb|ZeOy@brNR$#CwtI zM9iH8a}{E);xKnH%+-mxx?rwF%(VpbU}7HZFlSzA5OX!bT!)zJILu=V^J->BshI;0 zIvLH(C_TZrp~*7WO_=c$??tLJF?SZsRf)N(!`#&{*C6H^g1I&^*A~n}hRU1F~5Fpo9NYnU0OW)3|1WDGN-^aSI!Cd*teVa89q7pX49+(j@~Bj##gjz1NO zKcz_DHFq=KHOafC@UBDNb%gg&@*e7VXI*mCAnzK&yB>MhbG*kH@3riWQhNuUiZYhH zQF@edmy`9bpLpXZ-iuUM^6o0UtCM$ic-wc)-3@asVy-2a>k@Na!90wZhdInymmD>T zxu#&QPt5fl=JAGk9W$fU%wuH-!8m3{nF^S9-6L|$4H9Pj#CwtIM$Fv=a}8py;V}0w z%(aQRwqUMD%=HBGaAF?rFlSwI)FS3ug1G@PH*lCI80PiNj8ZcPo}4nCnNfOzasQNE z%?%S~{KR{a>Q2nv1#?YeuIVuMG|Y8~xsG72Pt5fN^9W)dVVDR1$0bK?Vy-Qi8xnIv zhk2r5-oVT#HFMxuDifF)r6(A7Sy|>r2{V4;y-4*S<{pB%7BSayn0p!Ky2M;pFgGCP z27-AcF^_bZvo1O65OW>D+=!SPIn0v`^G0SyshI;$SDDDnC_TZr7t1m?PMGl%??tL7 zG4~YAwTZd5!`$02*CXb7g1I3vHx$gHhKIQo##`7Jr8W*ckYx%Rqx1x$acqpz zdxh#l#(jiwJuWV;#e+YlsG9*gzOIBg1Bn;WT5ol?_p9!@%=b zrm`VQPbeDChA6#PsJ>*_R~XhO!}^Y4e`DB)3>yiDw0Atvg3>yo>@nksOG0Zw% zHX_4D!mtGywr~t*7{l#sh*BE{o~|;T4N-bR(L^>x>AgbrC&T{2upt>XbPNX?!zN_d zL>NvW!wHUI*72}088#M%Ey=K@V>r_o?qEZd+A#0{l^JY^(i4g%u^~$D6>0z(4iJWo z$gq)PILH__CBvq|a3UE_bPThOhfT<^i7;$MhOHdKS;lZD8=};PfoG)5WJ8pmP&Anh zQF^aX1IcipFlt zz++Nou^~!ND4N2CD7{yxL1Z{c7&alpCXV3{W7wPwn+wCqWH{L|%y>5x?PdX#S|IS$ zli4hQ(#sc3WdW4lE7V{T7%T*ul0Z{OV5kvjK>{s=z!Vag;s|8DQE5)AsJU20ZS5+; zLj-V98$U3>e)MHN_}RmTD79hW!6$Rr5T(DZX>5qndxaW8hC_s5Gcs)E7!EUrEy=K@ zFq}$;Qys&svuX=6Y#|KWrG|LU01WYj0nczR8=};PfoGr0WkZzywx+WoO79hFC>ahF zhRw;axnnro7`7tAR>E)^8BTKyv(Bn5$*`p`Y@Zq`ZHUJYc!vAf5T!N@JPu_Z8=~~L zHG>UNdaqE!$Z(i2Y(a)C9K#XDur(RB7KYQwaJpldbyjUfhOLBQhtx3AhIlrCXSkmY zQEJ1$(^BTMAxeK+GuaTO_X;(f42KKDmSot{F&t?O+mK-!VK{>fXBfk_IIFJ7xZ|}o z8MYRN9aF)F=`fC4}0L zP#Z^Rj1g*2LhXgnY!aFs3l+<6l&?m@Xk5mA){czY38OBlQBiG#=MH#Ahp`b#Z4`K- z%3L-=>1|7mCZo~9sI4_pxDzzK3d$)ZS3#-+8FdgwbI52;YBcIUjM|e?dtuZyHNq1E zFe*GNz%x3WjZkW%zynq0u@OpdTWSm$jS)ueQX|~P8DHfHqmE?MQ5el7qq(Wk=>IV4 zKt>&eQMc5nxHdw6zh`s=8==%jE9IA<^VtZcw=Ff6jK&J1_Nfu>!Gsa+zU0xUPGr)NL?8Fdy$JyRp}#A8(GhUZa5N3#)1 zZL~)2ON-bDrME3Lfs7^yqfV(2ZcW5!a8n|WMs+2luEJ;`87+*Bu${&bY8RiiN-WM_ zHE#tTEMpGwU5KZP;OUj}l+rxta_0d>$1o2{%@cU2$YSO}>1|6*B%X0uKvW!aOLwZK+Ab zGfD7tNqKN9Ab4;SAdg0MC!X$tXEE_Cc6jvX1peyjMm*gFPoI2VXjBj4=^=QQ5YG~aXK-ls^iAWV)f>MM zP2T(qqvJU~N*zD&%#D1GkJ8(gnnLlXi1^*o__(zWqrts&`q(R1 zfPDmDe*)|;0GAWsatAPYBJ7>#F6iEQ{%{7Sz!fzxTB&)!(a8*qQUeE`T(O>kQTp3j z$-pSRSEv~TJVOBYN`Y|;8-Q{18jn}?CE&gScmM$p5Wp)4c!dKTJeBq#;64I)PzsC= zY77{?(>&nl6b44AfdkL1SjBuOy=|$P#5Ys$^-lS4YZ^v_o6>kRsvq(76MO@SZ=m2? zNqj3EzVNA*`1%UI!6{#5&4*TK9&mIj^P$vyfoD;yWS7%XmRENN2f6#O3fE|2E`iYL+Ncx z%_hFtg0FANhr7wZhx^EQG-?3x4G?^TiEpsrTTOhc9lr4SnfUq(zM&~!Rn3RiW*%^K zI`g5_e1S(wtYtow-nP^n;+rG*`lWohQ4D;zMT|$I1`^*u!8e5Xh6uhj#J9%qHP1Xd z6W;*AH!S6=ruopa%ma?jU_O+ZFYttjbd(%Y7rM||@H z-++`4w})XgxG{`JqXrY-V8J(x_=X9-b;P&M;R~L5N2EMx6vlwiBFqDd&SD;vnkVoe zhYiew(%Y7rPdxJl&%l%icYa|sxaW&UqlOUA5WzE?c!mp}^~AH@;R&8u2h-{rELPXZ zln)KS7%*CYdBD-x%!g9*4VE9EZDc-_-nP^N;#(m22Bmzs=?kO5?Or?@HI(><3cd}* zv%%pBo;imQ&k(^gD&;}rE(U~_T^>-hi9@6GUZECJ=!GKm;50Pu(!%e+{aO4w)G!J? zOoZM@p*K3AgXg=U6nZE^&xn6*UcQ=~mpr%He2_3YOj# zaeS0Ie&9I-TR1*SZ(C|;8V|Qw;kV%iEBh?#R70M#oz4251yEY(=r*3 zWnvl(&FUDN^3>Hl=uG8TL|ZvDO79hFSQ;AlMIkiqh~jOikraBQ2)%?tFA<@)Q0OgA z=Ck8o4}I8aFZ_G;U$yZKzQcdXxygltM2Rp|?`# ztxo9RNn#|09w|bPPea$&q0y|#1CB1_9Ra1@5dyvS+nEQYw=Fdy<-t8l;KAKV{M*!M z;u$S?@`)#3@N6TVZ4OWHBr%G3Mlnz6d^I8EX`p$~WXS`Lc5rBv-Ye9|G&F81LTKDh z#M@9~DD)T+dKraYCPHtg(A%BR!IQ+qG!z;eF(9-w@_?e9915lP3NC?=tb@=d1^3e@Ys^iH<)-#NWfA zQ2Ik2n}#Z&LybkK83@2zp9^U__xOBbbHx`8I(ee8hJ+ZO)*gmqBbVLTl8;%5@YpCsb1q4;Y={Jj)^uM=NC z_|%U-J&oU7$4CDd4=B2l?fZ64o~n1H<@_wZq5xqH($+6d0J{7w12s;D3Bjr z%{(YIPoOdOAoHN~wxuSeJcTvSB*8P4c%}-T^~AGY@EjnX0}fB{5IHN2-%7_v=av`$ z5QjqPy+Tb+Llx1XCW}zhDAY6&Y6FGZAVM9aPzOz@_$i#hU1D|`3Jp~_W}}tL3w15e zDM~%3fhN<#I6g{mTWU%gzo?Es1@Yta-((ybyfegfa+oe0Hj=|e;c$o?4ml2?wI5x_ zDN*W_fi}>?IVDOz<MWZ`thfw@r&#D(?tB46o00OznS817V!_K_=lVL@$=vGA7AiK zfAeg7h3Hsq2<@%$8#q2n9Y4@~c_hb2>1|6*Pve)+@u!RUvnc*75r1w&_cS%Pp&mQ64a3fDt^3A@XpBv1hv3{+F2`s zx{0AsYN$XX=Ftp=(ubOvLgi_wnShFqn%(6E)f^I=BgE#D*!)DSYe;MxiER^NN0Hc3 zj#%*Hz=b5X&=oUF>t+^1sl@_qm&dReN?&YNDppF1%`#%~?QZt3E1FBtxg<7Mh%F$o z1&LUG>=;KZ_(9~{JUVXX`570dqP?}~ zVj+4fi=xz`i!u1(i&wAOkRExX<5(1>|J&xIqGhz`9EkF}!1)9@UqCJ*$VCZcj}YWe zg4`(}k0r=s9mvqdkeWx3^91A)3#rc&OLB~AskxrGjUiEL$Uxua@eGO5XPRpvldG2; zqnc;>xfT%Q0s*<0AQvZ)JwuSY2y&NzJdPlbb0C8kUP~>M0uuIN@bDUlZf7Wz8Y<9S zc>+VB^tJ^K`-XC^UUA^z-=-E4)ItHZgrJrrP`yG>y9sKyfI6O_jyF)la6;A18vZ3( zzJ=0roS$P-%glnXlIgLi0A%Vv4_5#LuVr z`EmTB`JMASg#h*vz+M4xA_1J}00b{2mRkTlcgu6})e5sx?&6h#Qm>RiALYqRh0=#u zXsPsXTbP4Vi_A({LR3ox)iR=5W~qXg^ZSTupP)L4s7`XIf>#iW^W5{{;ygdx3QMWL zh_wVjUI)=B4205q1sLpF0#1CDk|Q#g3rh)TsQ_9|K+7#q@G^cs0qqw+Clk=g4p8ud zVF>{(@qwaycqO6KD=E-Pc`8Gp^r048D7}&v=a|$Ivy$=&DqldYAgC1?HC(q~v|q4bJcnqyM=W<@P0sO17` z6+x}CP{C{ULj-k5K%GWVrx~cY_fY?(#=QJh`5W@*Io*fLh-#Ujx}T{~YN|Cj$9UJ` zXD}5?pDN!{DKKG80mxfZD~M`^pju5-t1VUVYWy&wI!sWVPE@BmRQj<_l4?0oEf-V| zFcnHo6==gelc`Yp5X&r;URBF-P-?kZRV#^VrJ!0vRBJ3%@Ot}jqB>kqok3J*I8^%i zPm*c{QLPYE4>A=>O%-U#Jd3GN`c%s;l>!r16@a`|wTh@#397Y3wboJvuegsOsv`u| znM8G_L!~bcB-KiyS}CX=Vk(rHD$t&JHdCSWAy!x_y{cB^pwvpUs#X)#YC*M*sMcAk z;5GM=M0KQ~I*X{za;S#Ht(=l-6;ZA7snmv+?v>VtmR|hm90o$^y#fsOItn;gOJMQV z(i#FQ)fvQ!OO0T6=IViQ-tfjR?wN_AVAgT>9Rk8e5cmvZ~zkyl3a?QNlM?LCj!a7=D zokLjXI9M5n^Gy~*0RnRk0-o#WQN}>2F=R(4BHMKX2y6=kye+kkFxCl-jfAn$Vsr^( zoJ(QPb;4#GkT=_~dbT!;sE=_}lsaml_wsz+iBS4c*H{ewyVm3=)LOGL))U5hfw74& zHd&0WVT|(#<2(l=e8`O+=ddVs*gzlT1soQoA9k$`s}K}3kBHvPZ=kRnMA*#~cC!uJ zEgbfI3VXg2Hhj>Gp5U-3b=W{p;)NU*r5|OT4XbB%T`sCxZ)SEQh21E^ZlSPSY}oGM zu*YBQ9?*}!*dNaYgmHnvh?|_k2gvA2#z3ht0v(1IF$PNim#?=N3J{oi5O_1ci7++^ zjID&R)nfDrW1K)3CkTuS3FATsBYXgio?;A?8Y9pzcrjz3^rLRD7A0VTr83U!p2z38l!WbxhjExpU0Rk%n1m4Qn zLKs^F#&*KkZZUd=F-{_klLW@agmJNhk#T^0hA~iTj6g5nrHp~nkGjcX=#{Yv6f;1w z0bgj9v44npvsofrNoA{0*+D8htV-{&%E_d1vQW8%R4#E;GLEFrvI~adZoFZH`;3 zOK^k_t7;EjYVFBgYN@^EBKvs;L#e?6-FR0p7|ImHtd6Y~OaTiE2~3vEykZA|?GRwQ z32b)`EaTeqGy*$KfL%^tmpfqL^#c}r@eC|P024=uUSKek8chD-W3|n4==HNLhoQEc z^|O;Wb_$L?#IYyGk#Y5TI&qvXIIbX$D-1`g%xe_2&vNJp`*Ij+zga&oG6zb{AshA( z+R}mov_N25wTn1*368zQu{Xz&aeaCQahxGIt|X2t9gd9EvEOn4CXN6Eju5@X94Ix1 zY~WKnEQhAuk;70s&Fa`q9J>X_KH}Jy=7LMiDQ3`BjXzOEaEsza9m9sS34XTtK*>M zP@q5rAaI1}73M&xIpiPaRl6*QrrnjpP`l0Q*h?IH1;+v6IFRGWxQacSIL;Ov*AT}w zhNDCF>NsRMbc91W40V`U9j`J6O3fjg{1Do%4p4v=2u!Q?5yw8kagaC;<~TC0W6vRu za|Fk=#Br^|k#Q*PcgQ=LxRsiR*fYE92O*pSbo5t|KfL;Nplt z;)u~3%!N{O$woxA&vGSGBd`t<)US!#D0b-_({GxL=uOD#1SNML?Y28EO7xzTp%QF zB#9dxiHtq$AT61LV#yq3r4*E~WZ>g1nYUO9rIwO^)KwiIsRL5#Fp@eS)4w2L$A$7Es(rfDIoRd1ntf~L86iO{6|1PUKNKyx-)Zrv` zxR5%Eq>f6Yx`m}KBB_gn)XgMyvytkYeNI1&qz)5O$5<%^C9EmfIcx`(AMCaH^s)GZ`+izAhBx<8zx4i{3#S}DDzj?Fo#&=CZ2gn&5CLMR|$$soSB zWZq>6lo~>ISgOMdxfd0O7xK2Gjv}a|1k|wvb!-CFGYoYpL0u}KZX>AM9H@+=(2)dn zq<}i!Lg^KAe2z(-U{=g~424od$zDr!1VJ4kppGV}qXpD)1a({j)hi5j89`kppl&Cq z+YMBg>{I+v1a*{vI>ACIAYny;$6HbFGZabfT>VwD%tA^5POvk zrucdyhh;wfJC>-96;vk>)d?|GvG^Y1FxC}>b%nsXld$eISlzNuZYNm`1qcKHfwyix zWDJxVL$-vfqb){q$&jN^$C!0<9AO+MFis?l6D>x@b@Y{laizexi!knTFfvxov9xlI z6)Wdti=_jeoTE~wn3eMpW1-YovVjyNcI6zcR}P36UL8+Z#|x~J2lDH|#bRY#a9=}M*9fe83F}^i6+d1me3Jko+W>$-01$A1=u^f( zsWD_*sXE?bXxQU(6zT-Ca!w+QlLW@8gmJ3H$hfAymN2dr821szeGW#(HT8+Ka!wR0 z=X8su1D>9vQfHWz^BH5I)L62k6eJcNP=E&!!>f}C>tum-8eyGgu`;f^uOqDM1lIk8 zb-#m^aov3qVVxwf&ahYtPzVSj4j6sTSSU4?Y$jDFS}YBJVvb6kWLDNGgmsF*I-Rgi zw^$k1-q#b>^#bbw!g|2L$~Y#SOjsuitTQc^4tQpcN}Xj^))$P0Qe(+JQIOb`1t`FS zh~d?#gmtRGI)kvzuvi(_-!~A}4Fc;y!g|nP#Sgv8*bPr1tWyNmSr$tH3IRdH0i!P& z3#G=Ay`bu3i>2XD&QYmT%*r~AuucKwDOzG5tt8cX(rg2b*YKmi^^46jZntkVV7S%h^~f)#(t9sKb2Cc?T& zU_DG&4;!rbkz844JHk3mV4Y*J6rd0gL>w^snz2x7EZGyPPPJGX{?r_mI?b%CGYIPp zfps=vot;a7LRgPDSQ)$F>4bH44|vsML98Wqrd~C^eS+ z6PzHiD+^G72NA=oGYRWVfprdHonx_#5Lo9~ECnb8 z1Q7>}zGWny@LOJJQ#Sm#=-rD3dF3F}sY^%!A2=3wbZ z!^z%;GYRWVfpxyc(gDxUQK<{e%KDD6P--msM>#=aR~DcE4}zGp0y8cX(+sxvK?hCee$rOq-d z>m0&5M_`>#Sm#@;Wnrw_3F~%&^#ox(VX)#Si)9?(&nB$11=fWYO9#9#N2M+@E9(cw zLaDK2UnxlJ$^sPNLB#OtT*5k6U|m317g((2VXQj{>kfhSBw;=2U}YTO&mpXH1lC0s zO92W2LBs*09~ld!#*)3I>THXp;m^)dsdLQAI*+i<6Id4#)`b>pMHuT&!n#vnJw;eg zIanD7_;U&CT!D45#nJ&U&QYmL%*y(Su~2F(*-WVVy6qF11)X;H5b#b(vXNzc3a` zjU_uwL1I@Hpa2gdhF2F7)`bG=62iK~VyzBi-9uRS2&`ub>sf;pKUOc}0Dl2tT_CV7 zvsemH2nZq$82!pvC^eSsF;(YVEDe8tj!Io%R@Oy?b&>SQiSc%Pp1;czKRWU13(%Z;XXfW63`l3KF}r00npuF}%8%ur3x@ml4)w z7He%7>psG|PhdSySkF6H83*`_2hJalq(z#zLvF0{x^HS}YBJVU9{& zWLDNCgmsC)x}2~sw^-}KSoagw{Q~O+!g|5M$~eGZOjs8StSc>+4tQmbN?m1E)*p<8 zQey@BO)s)o3Q&Lt5yPuX3F}gUbp>HvVX@YSu^u3-2L#rOg!Q7qiXYsVam>1eur3i; zS6M6tCo3Masj+0oD@g1y3s8Uu5yPv?3F~r!broS< zWwADfu^u9tTWQ3SqtCU}YS$E+?$Z1=h6|O9#9*N2RVaE9)P| zLaDK2M=eO~$^sPNLB#OtO2WEQU|mC4*I2C0VXQ|8>k)zVDq+3qU}apCUS}~BAP@iq z93c9aF;Hp@*-@)5w-_4s@*IV_!mOOD2;(Y&aV=q7YcaNjF&-t1M+L@fgz=ie7?OPe zzmitYm15;wZ?Sa1>vL4<2D5Ssyh49Q9HqvR9k(E{D+f@32NA=os|o9Bfpr~WU1zbj zhOu5JjMp8EjNRxe!njIc++Z;jAP@iq93U#l7$`M{?6_4|S_}<)WsX8!Wme8LgmI0) zxSlYsw;0>P7;g~98xDqkgrxi=^J>DlT43C0F?4_%a}??(voaK8pwt+$(H4>I$^Zml zLBO!;TEe(iVBA0$H&~4AVT?Bk<4uDRKPEEcI_Da~xJF>yWHA&V5C8-mAc`0RrN)rm zwd!h%p<%DiQK)Oo%D9d&t`itH62^@dV@DX{Ey8%q!N|Cdxt1`l6&N>L3?1O+9EG~Y ztc*g8fl_10&RImZD+3UK1p&jV>j~p}fpHUI++;C!hB5v}82@uHGOkmuBaG_=#w`{@ z0RjO)zyYGdjDb>P1iE6cwHO-q+8l+t&a8|Z2;&BUaWi4uY%z9)G2SMOw;ha(1L*aH zalOE})ne!Xx8^9+ZOO_&5If(92QCC-E_EYCyir8Fg(BW!Bkm4Ie1{^w<3!B3dboii z-XJ30W+N)ZLjVNh08vq%Z5+pslEjTd;&v;cM}K?HLET{v1I1VZr5<0P z#q|a&p`ZX&GNZes16cjLe zWw)Eb(2{Ww~)jwLgIFkxIK}Go6a4H7mdXGB=NqHh#y@R zUK4lPq=i+p!c zzPplq@jl_?d&T7Yi1K~pk$BZed`uD_8;SJ6FXHHRJ4xIwB<{5mdi3|^9MpYg zpDxW3D78eOE%Y`kp`ZX&-JdlHGb&)boB%}9Jg5}!B{;WcpwN!%eM z?z0jK3K%`|^XQ{8EP+x>1lm4tw-Q?Q_MC&d!>ozBNa8LbaW6^Sn@Geh+>XTSM&eVF z_|!S z>HU=S{v>IRKXN4AG7?{q#21c4c+T%3iF;V0KtA%?Hz82K z=#igCA5~xplv*OtS9!OU(5iRm9MnB#P25Kk_X&vyN#emoBHqs&iT@diFG=D{BN5*= zs_$15$Nqas;$9)~u$9oGe>mr$9x-d8B1@pu5`o6ad#r?l0#uQoRn`3@alepwh$J3L zB;x(hk$Brkd_@vpITGO`-hCu-pOARON+>8`^vLgx{$86;Tiu&Wr|vT|{Q%{AK;(Ov z@;#j7i}x-k-#aGX*Oc#TlP~?tlwzjur+oJ#-wdR<5BvQqc|D4^P5%~?dejEhF&@pu zRF9b{ugp`9QcroHukk)hqQDXVx*Uq>YkZJM9uy>x5XmD6NxYjmB<~uMZ;0d@LlS>` z8J_Y7h~xn=<&Rkjn8c$;exCBE3QM5W5`m`1`>ljly+7xmo->Q%A(D7VNIXgsk0uiF zZsth5XC%HQiEkZ=@B#5bl6X)^JZ>fQ=pWBHs3**tsLB#3wM3v}@d1)}021*+tnB<{ zH1(h%d6-BZ79@`m$zusg+==Xvyl+UpBa-h7N&Jy-cyT;LBo7IaCoG8q2Lb@XTO8Gx z1f?bk^d&xMNfbD+E#%iIogEajzdS-Dj|h^-iRAHwB;GR}k`D~Y_eAo&LlRyk4-?75 zg5*g{qF2e2IS}=fStZq(1f?bkbRRxsN%XcJ0!Z8BD5V}Yi{nv}cvMI{K@v|S67int zNPK7{ejte-Vu@n;sxKDDX#6*>Nc^w-kH4O>X%&)U(vZ=PF`28V2B$@-(+1iLAGT=~ zl44uP$lFqnQQF5u+9xUPlS$fm?{m_AWYYdfX@7Lmj>$~>D9!z&V(y=|8hXB-&RM8u z%-q*x4U}3V&_DQy)zI5|Bxj)>HFN(sX*@18o+6E>5{-Drb2L6S8b6W7PmadeOpV7# z<1uK=z^pwgPo~dU76lT#1Q_1LK5D}%1dTV6i)(iICn)R_BJ9%?_UR;Syh}M@KQUo{ zrm#PoT|Rzbg#JrKrSjLWUNLXOqJ_E3fyXK8<4)99`MTj*8&%KRv$>$^IkN(4^9n$z zS3sc8?=g#_xAj<#L_Ka+z>|dXq(FIwP@YLp;yuqn`P88NLMXpDDEhAw1yG)|Sru|( z(vXm+HLAl|QR=LLHoeDfR)w6{783Hd)Kir8DUtPA%KB`QHQukBte=^zzf#s;P1g9y z4p|G}Nm>9;Itu{T3GRjC^A<%<+VeRQ^@3Rdbr}VvMhUdzJz-Jwww}n5s3*+=c$!e2 z7AVgV%5w=y+<)t!d~Q&FBb479l&l5t6rnt2P@a?rfEO%^0tjXo6g<08Jw`#PQ37pu zPg)cO5Nrz+ye;(%p*$l{p0_9pUj<*8gbRnOJSxuoh9Gw%&KD@y(Q zSK#;aUnf(~*sOY6&*YM-XU)7nPg$QASzk)C;tQczKFJ#IZzAhol=UwsYu3EKVzVmb z#MY6J=OSvvSyAe&ftIyrZC0d?w}phfE%gFreL-Y>In9bMhp+{F85GZJyg&I_qrd+x zYnEh88<+lX`9dIBMkJUJ(p_W-7~V_eY2ia$@U9$m5Hea8{H$YoMj$4 zKwr;AR&SUIZpxui>fgTxzu()nU$CJS0%N2|sAIQvVw*F`%M|)$5&E?>G`=8;=OPIm z?_(l#fxn$)uL}H~{L(md)=a-)Ln{Qv))Cd4>1G@nr4Aiv@p{pQ)_^ZMGhNL7S&f&> zOus^*UlE~SPebFoAPfuN{lqgJ?@A(cK?+^agpU6jLe@;bX+!IQzL|@x-ZC@YoI|73 zzdz8b^^y&(5Evsx!gQu>Y%|lZQs`Gj=r_{P_*y8QizIZsPl?cqLMtb9)=a;W=dKNW zP|EX+==LlQ5d3yf@GGJgjDk|51X{9QwkR6-WsulUJYF#i;5D*%O<25{THuQ#j0Rs6 z#S0+b)r3Vv7Ll=tA6TEY0A3{vy!o@^Gc)x+YoW*gznp}6+boclY=KgbFVJ!IinUO1 zKoSUezwLFhcwJb$m0IAdqj+W#i+B$d7KO;7kYkaxF5b3T6>?(hNXX-hT5(pCI%}X| z>Q$RnyS<8}GqA-<&OuMTW){F36#5Mj`hRI?d`pCl;9H@10mOTt2wj*$7dD~er$c8g zfOl+YJd=7(rq^v~4fr}D+dcdZGr@0B*0)5~ zchao*atNcrmqGCa$9s^-T9mRDHCf{a6lYEFdp4^c-+Q^F>U}f8Z8J&5Cb*V)-O%ya$P_#VBhrCu`QczHhTCMRH`~E5A=gvWc8t$;PxCErT+baHlVj`XobKSDH7_~Z#c2dOus{+-w~nT zPeVVZL*px(ICQ)RiO?k|bO|T4zF9pG`a>I9AutAtsNPI>;Ls@b?+>*5{LhBgfd4a* zni;d*Sj1)_o~eW+-s1#G z9+BiZB>L;T0LjM``C}2e6Guj=BL`Y{-m#H2-a9666(_KI*Q|o~Df0Uw@<(Z8d}V{k z_=+Z81@ZnSBA24brJTs^;xDKIk>8_L@Sa!&pAg9>f}}H(pwy!aH1ND@NfbDc1NrqT z=;EN5Rqz3kd>}|ZPD${+4K{`EX=0LiZxke@iKMh4i9d_VB6*)k-WMdF63M56qzjXv z)T0Zu@w{hA^eTA|AogtkzF8a}lEjBX;*(SYU+O>tU*g0P@lGft%8*1EBN1QDWl4NM z5+4YO&q(4kA<>m3Q0mbQ#^}5^_U~H>1qI|lersXY#789Yk&yT_mB2SS*aE(}i6!EF zQ%IC0iLyo_zV6AA_>d$%6cV44#OFey8%vcO*uQg1rY zX7iEFlbj5lS+OTD^|6_iPbtr*BF`5#kKWW5Nt#ZfG!-aK1(PQIBF;;rKA|=GiN8jp zo}3n?P8(>Y`PimaAL-dcv~>1tUNd{2QQFT$+Ak^Xmq=?4apvDwq>L4vjG-A*pHjw8 zMaEv75v9%;Xp;HFX4KR0iAh-7IT@)>&5V9d89x^pzoLv^iHwyfVN7iXJv*Oa-1f})xtWwNX~18K0e?dS{zeSA3Jti58F2a?l|Lz8(15@22ORa~ zNkOS6CBE0*o0QLOG=$X0vs^ec7hh4duSB$ODcZLpT2+cx)rl6Ii!UkKmm*p}j)qc4 z3pBBOVWTC7HUygypLU$proJ@O_cdkwT4el=GJYpAR-=s7Ovdz!CV%?AqKsdOjQu$y zN}X}6oW3t@M)ifBJ_OP!KX+1^dHjYlej_q|PZ_@#8LLyq>Q2VsJbq0XzZMw>a7L6m zW1#WmE1OZz<5wnOD<`4)+RWp(l<`}U@dwKIgUDEeGS)B|)9;h~dHjYlej_pt1%0 zV68vENn!MVpbS5V3_nwbpGAh+l%ckhA*la7>3=Wuzq2FP`rkSF_R2_oZ}fkpk^d-0 z{tJ!#7cufWH1axTmOoW1x58XPZ$WALbE(^gIr6Qkr@EjWYfwGX6;!{}dS;QpSc( z#^5~uO&R|d8AowOlsaRe8Q~Y3QP1NqNNBIle>KzhJ4O3lMEi@P{UxF`qG*jwwDgM$ zfBOERX#a?4qd6K%9WBsQ@T-lc5DU|XKsKD2wLd7@A0pb{6zy*jtuaMw>_pRFPx#UP zrD*?(Xk$1UN*yiGLGYW6rf2Op1e<|?Eu3|!emB$iCuRIoWc-IR{v$Frp^QzOjQZOM zKVyMb_8y7z%f{#hT6yTvSWbyjrwnuk{BBb!B*eB5N#`8l8 zrIbybl==$>KV`u*tAN-LL*M6Z1C>`EN1g0*%}=X@N%R7EI)3 zG~{N^ko6~@{*YBV_50xp)FP`|{&1o+{6#u^B*IVN@F;coz#aU5+38m%{%m z!Yc}|MEDjIzJ&>&e!B06FG%4FitvTf@E7awg+%y?93G_(AGlNhZyR1AIA$J^y_qji ziKe2G|NkQjABpfSDSS&4KK(%753eY^65$J{;V;qQ3ybiRI6O)nK5$3=KQ_Fc`G0cJ z)xT!u3sU%kB77kVU&s%S+i=S`dU5IVwIZHYh9^Cn$_M*J1QZFNA}P?N8mNc>n#@2b zHBjI-{eLZx0uELOSiIGt2uKN_!UR;<2U4vmerqRw#?$KxQT#$8e$h1kWjcOQ5q}ED zN2%in?#wSx*qJ<4pl}*q6)c=QbSt9xk%(V};ujI|+fe*APW+7L)u~eMkW{I3Nai?Q zn0N{co?J4*jI zv?ai{4xm2I2X-FH8BXu#qEa2f-m)PR8w0c8R8@kizORAkmyVFD~H z0E-b|F&|L1Bc67KCqC`!9%0E-l;Rf^@k^xfuhj8Ni1^bvK1v-w&=L^Y_zKaneh}JQ zKSd~h5fQ&Q#V;=6x2O2+oz;;Mzc8(i!eVt4Bc5V{r)0`=mF6iacxEsUO3f4KA}C~e z^y(;-!%>CJ>L^M)MFmd@;wd3`IuK6>!xMk8oU!v1A)X?Fr#SHx7d&|>&()eIPw>oS z9+aAAjr_2`u;o#p!Ri5uw|a^ZPcgw$l6XoAo{q%R(eT7OkG?}sw3HVmouWdg1nHCz zI;B#bYqU-&p)-qhP->k(V?q(DqZdz+oQ*1K7Ef`~DK2#KNGDI|bRwNjj*dQa3!P%5 zQ%vZTB%P8%r*x`wt=1_mbY`;-O05&2!8< z^od>Q6epeHLMM-O@`O&AROdRaQ%2~_VI7oOC(z1J%B}k`)&?!YarG!q|ROfoFQ&#BAWgV1SC(ztb-0CREVC}%fTRVBA zlP7e_kWLw))0K3(Iy&J!t0d`^6gs6zr?k*1m+IW0b;=2yd8~s{>jc^%N?0Aec1q-I zR7taTN|8<}p;MN0$_kxsq|?pO3GZ2Xq?0Ff%8*VOp;JE9xl!ws7drD<2c^~t^i7ns zItnsaJ23IqPHEC9Ep*C}PC22|opibzo%ED0_N=m$zN|=JAx(diPG3Q!U%=^6>hysI ziaeWMuZ_H1c2&x(jWU$Jj7VRe(w7(MdrkqOm%M7 zIu(V^Le@d4bpkCHrL2yE4AurrytPr5bjk{y3Zzp(==3C=o<^q$bVkH?Ap4)hlp&ll z0;fFTlovRaQk+{fP9=e}h;dMAoIsC8X^W$mPU#$tDr1&TIl?I?a4Hf`MS;_caC-ST zf!njol22LTQ-ORc2%pNS&#l_0vhZ2VJ}9+Mpq-~{c*>JcdErxud@2c_ z-sIC8KIZdp^T9(!N?TE+t&*m_O{c9Q(k|h&D0SLEA4gf6Rtw+CcY4d7D+Ik#;$!MXA#UdM>I^mMS7kb;?p*WT{M9DvK=D zC`&bwrDmGtZk?s3$g+a7pww9cT@zI)OI4Aj24$%svQ(igRYaERl%=}JQY+1JkIqs{ zWLe2sQ0gp!zK3d*rJBf6ld{wlS*lW&sv=7b%2GpQshwuIS7)g$vaI4PD0PMVi&g<6!QmdH|YEqV(B1;|0Qb%N|pJsVbXQ?l;tm7;w zb(TP%LT$=YTV$z6S?Y-_wJ1w1k)oCT%M66j5+M_KBLEDb43Ly@H}WvMH&G@vXE{4CKX9w|ya z(y?*{)u)lx7b9&%BW)x`T8~CrPmHu7jkKW{>1G}&NYb@e5qj=3kyd4}5rH&UrYu;O$O(|Ye z5w8WsYa!xIq<9mZcyS{{M!Y5zuZf7)oZ>YX@pf`NlsaDg+;}fuGm6(t#A`|MT8em+ zDBdI|-XOc@$;H`};x!fVT2QE2bR{&Wc+Ew;Rur$5h&P$yP4?nt+vU?&+s(EAIoEXb(f6)DVI8gq8%+Qb4pJh&BRZDnU#&5Xng} zU+D?;&lD|)p@m>*O$@CQhWHZ#Z@N`GQfMa>_Ob#>tq^EnXhjOGghE?VXe$(^k;1f) zg4}Ccl0!@3(1sk^z=1#gZcp*si}?FEK1v-w(B#mX;>BK~xWKi$NSFBRg0 zRcE zf||c8v?hhtLZKZgv`ZA?4>Ej(j-=30C>&q~lv*LsFVU71+6sjZq|iYq%p`@GMj^g| zDZO-*yFwdsXd@ijlSBK&K^#E*IRPUY=LqMeZFND>`|#4M7S zCm1W+6#wH+xQAyNujGyIGhzwYK1`SM!Ul9g-5%>={ZTwGv9=DB&UwT zsS7!E@ttt{HFYnbOn-;@)^{#R&J9V*BTNUf>>w;VlV#_`GXB`ex9moi-Gt>4Y>84^ z20B67lVy9ya=x+bM3$X|WmmH7>RYOLBsI^I(r@FXR7aBPD5ScORF_05{@BWw>P}MK zh18KOg;GleT0%OIR0l_DfsyJ=Qk{iVHlsjK6()HwAZ zryjzoH#zkdPD{vXiE)bW?@r!`#__zT7WN{CUWtRMuL2T%NusZiIG!a?YKb-2l=rrx z8%cC?B=U_!Pm<^Ip1o}m~ zlSFq%VwsWXMH0P)L|>BVD^f&^K|2KS}i+29U!5;cyZ= zpwte59*~~o(9>~PVI2C9Lm%PLpB(xNhvnq3Jme7AGfKJdd3u-fPbU3Hs$U`%f7I$r z4J4_7Lh59eLaC(!{UE(as+S|R(n$3sslGyL07(rHQY%Pmg(np}>+~U~KEkO#IrUGR z;!h)er$OX2NI0FsPAIigpfjX5IrVm&RvD*$8WPg4Db)F6@?WTeK0q=u5zP$6|XOQFjR_lz_ zAhH@HtcH@+P+_%}tkxQdlDJ9QVgcOXRz3NhLO~;L@NGF&zBlWQX_@b*(`-pO9h%y z29eYtM{1*y8cI?_h13X=8X=@MkkkfGD)>HP2ssTAPQ%G*c;cj{g^tLhNNSXjI)|lD zYN_}}gQo~4Un2;JtQX_@bMv~fSq~d4Pr#Hs==dPh7HB?BAAgK{XYDP$E zG)avXQs=T1N-Y&=f*C?mLma8iMrt@o4Hr_QNNSXj+C);D9I4FDbw-lJNFy;bBr%30 z#t4b?SOTS%2sFqHC5fSq#1%?$J^4K9_h z@D9!W8{?x0ZB&95exl3BMjIO2{xL*MgxpLJRL_)?u}ki-rn(GR;==DXGLBr!gbh(G4?SHvW8 zm?Ru7VF#4jA@gApu_iLVpPNh)lM{*f zV_yF_F^wFi35P4#0i|{bw1tf)hw+ZXKI1Tn93}~espK$KIP4{dy`Dqx3_FD!rX&vW zhe*D|baI$39Ij*sl-gme+%qPS!vx1+zj2sM4wHq$G;)|G9QKjJKF=X|2AxU{Qxk{y zLnPl}206?S4p*@QO6?G6X`4t66CH;G#$gIMOc4&#$zi&1*iR1o9f$ZGbH+_t(@0`k zBB9VNEiGn}#Y|ywHCv$67J;U@Nn|m}u{dZfrjo@}VKIX&W(bP|WN{#5;eUECrIh>a z94^t_tIq=YYC1_xH&UxZXV_UJHA_fc!%`@6CK1NI8pA&JrmPQOZN1l=7Nt zCgq%IW*pt3GU*&jI!7eEj+3I)NdsMbGbrf{k#sgCoh_0cMoABIlE!aTgI7$mDCaDb z^G5sy95JJFDd${~^LoySQs)e`?@gnXJuSDg&CR(p$zi5&m_rV8gu~(FaCpc;&iHJS zm~A9(3Q5c(iFrce29`jnB?6s((@A2wkeEdhvxLN4l9($bjv$F6j6|{;GS3ThNMeqW zxH%*-pCslBi5po0rIrXZ1M+)W$KE=xSW2qBq&7J71x%eoX(d53Ak}fq#ABfL4ob)bEic%*HwB9XDlcJ>s zNf(NwODO3Qk#rd)T_%#AL`hFFNrxb1e7%)%3|UOakj3H{l1~!(MnYeKu*BUgfl^BZ z+V2*n5@=b0#3CWFlq8l4iRC1*Tu7Wu5+{2S8ONC=B(X$DEF+0!MnYeMu*5wqfl^BZ zn&%d$5@3K4%b#a}JrpHA^l55<>z z%5nl&E&x^$z$yXo00W@Z04wFC*Rm7=}Gl zx{~6r6!F(k{52x}LmVHajvr_|Tam^`LkZ%emBfp`n&Ph(@z+uObt3**6#pzQesK0z zQT$aR{#uH^R>Xgp6% z*G~G1!T-#DHN{^o;;*Cl>qPuVI6g`pKhR>fDvgik55z~?hZlb>#a}DpZ=m=aMEr9o z{yCxe^5D0g0T)PMav+CK2xm zj)zjm3$$OYOXH!T0rA#}cpE9+MiFld#oHp{T|n_JaN=by&dn5WvxxU3$3v;(1$w5| zr}5CIfOzXgyiF8ulZdyK;%yc2E~I!Ddhvp@w}s+uK|DMxPxUGkxP*R+lcLlw4)i>2 zNRy%u0ZBKAq?;+}W|4FoCEX^HUPMVRa*}3VLu{p_Tg5~^&GAs`c!5TxjcGhI4 z4iSGh#osOB@1ywpMEt8L{#7Qv?aL0v-%IiLiuea8{s9sHWsZ+h#}9PU>`de1)^)_+ zDdO*;_YX{~*ObDB{1u@lopdfd-jfX?)zV zj`+Jo{Jj)^uZVwu;vW$4uc7$YIPo*DyY^H3{UZJ$ihoGNf0g5-)bRuDF1yqCxJe!H zcZ>M@DE>YX{~*ObDB@pB@vk-U;}0+5GyDG;yX!D3tG0do%o-SS=@!hQRv#x#5J)3)Ng1g@p z>UX93J)nLMs(%dYOVsrPr&vCU*Ow>LrM^6q?)~Kd1nPf6^}9p;?o@vP)L#&(pZ4%4 zM}Mw&N%oi24S2c{Pfy_KNj%4qN22Bl9BuhH&LfYj3(v>I(-nBS5>F4{>EZJvmc+l; zmFTx!2!IPCfN8&d0Pqt6><)n439uIc_9DO&2q;kl2F}EEi37@W?gH3_0J{NTHv;Sl zfISJY6aq^00T%(_A`2M9OB1jM0QDfC-T>5_fKDQiL=6-;DDz1iNFIO}pic;>I{&Bfy>j*pmSJ0AL>iEQ^2=eZZvvxYV0K{b(|O!rcQ1dk|r7AnZ+q z{eZ9^5uQOpiJCBQqNjVDP@cmV!tO-a3kZ7=VP7EZON8Z+P@+$`3<#H5LOA=xggt?< zClU4m!ahXU9|-#s;aMbL=6}?ebgHOdlO(k0PIJA0|9U#0aijli9X;e09<7OV{gqg|5~Om@bx9W0l+ta z_yz;tVB-4{`6Oz-z@er7z|)_21_93?;;D>05`CW4z_Z%&xX&EYc*w3F0QDoFfdDj+ zfQA6j5CS@nKoT`j;H=XC02)9*g8^tT0aZaDi9XO809s>#-1RH?OhJF(=}$a^fM*c# z3l3GYck?8ZR1DfBn0ST(&oJVtjyw{5p7p@9-tw5AY-xPvH3)bH5zkQI8S3*SevS1d z>iU5bR70Tt5UM{M>JO*-HL$)!zy1cOzrogzecYGkXI_J${$Q#<4C)V~`rlxEiMoE^ z;MAZD(NEU~Wq`#eoK8_g!DlG>i~yezpbgeI)umo4{w2^@)AoO`5-Y3^SBnXWpp)nvdhJ@;(kVIc-D+q11Lhv1uEHoMfMw7sg zC?HV_1kQ^M2Z7<9fLwz|fxsvd7z+YpN#HsZkmw6+1A%Q;Aoe%%v1?2kzaWeOfiWTw zd-AJY;F~TIe?kn2`acewG8+LHBRq_YDQYxej3$h6fH96Ru15@sKE`&y*lsc0(;2}J zaK{40SVIvzPvw2pMdHs0AyGpF4xx<%h>;921|Y@|#CU)hPZ0GGLZT0`10Z%-2zOr_ zgcuFijnQ=77za?}?9AL7m>D&(TJ+XrVl{7diIv?oRdy-`y@WeTZWMHPu!C2*>3EU1k2ROG@u0aPZC z%4ATPOe!~_ibP*!JgAH(l}Vs7$xh3op^M8@aG6Rj*U&|xb_pDJ8wW1q*kvNPOeB{n z;4+0=Zblc0zRLt~nLsX+!DX^_=@@dE1}@XcaA0l{xJ+V~so*k|TxNjF4036JE)sp0Dc~}N zT&9D|bnEhL$YmC|%p#XR&_$wl37n*x3@(#B7x^hX4P2&?%S>>YNiGf1MWXLA6oF4M_n7P!nJmqzF!(RY~!F4M?m zCb-PBF5^P;G6!7dkjr1_B2l{pPVP+wm#OSB16*d1%WQC&O)ibmMWXLA9bBf9%Per2 zWnEqfxy%KZx#aRUx=7S6fg^v@z-1b{%mkO2%mtUZ+*8QWg*PVLYkL!M-w7&i4wI-;4I@TaGAv}bHQaUxhw#e1?18kT_pN0bHHT|xy%Qb z`PSvtkjo-)Swt=g=ps?O1P(#Y2AA2Mi`>7=1DAQ^vJhMrl1mG8k?6b31(&(xvH)Bb zSeMsAE{nlsF}Wyok*Hk)rzhut%N)-|-beGnWj?tq0+&VP(h^-H`Y!XpWgfXK1eb-@ zrE|z-3AijFmqc`ts9gfbF6V;FTy|LiE(^$IF}N%ympjl!qVF;vT;`L@B5+w`U0x5l zECrXPN!DT7Av_=<+zRN;zSx7ERz-5Vb=@N2T z4lc{dB?(<5YL~$I%?04Hz;lu7%VKa@OfJj7Wf{4&K^KX>%OY@DL@rCgWvO-fB;b;m z5qnG2y#og~7eeoa*gHpxS^~9~Q0?VVdpXs<6KhNKYcGRZ%WSPVp?_~^C2aRf+U`tP zTcWNVIIy`0YA?dtIaAb9sJ)bGuYlSssCHYdEzz&N1a^A~?e=nDS#DW+1$JAl0+v<8 zk{MYfYL>u3&c(p87+G?qsAa&ij969z%SvLo3t1%kEK7l9DY2{omKBzzcZg**u&nl3 z)W+74dsRu^QWCQun?%hPH~_i?*p?t$?i95g*p?I9DqvehZ0(RuqPJGH4A_R}wyek|QL_aOjxGhZrO1{iMXdm~6~wk0*j5wU-N+`KC94K7|Y|D@>Z;Dz8Y%7Uv4X~{twtJ9G zqR+Mh*j5nRYG7M!+4_dq)&bi(V%q|2TZkHSCfo&zRtpT<*hAs9p+yCp?^?i}&Xq1}gQ5`DB)fVPUz)&kmEJ8J_&v$hRbwh>DXWRa*@0tZG{0?SHdDUhPp z0LvO;Sr07hiRFG|k?6Cm2A0*tvJP0*S(ZT|mW|cm=U_GekJ=7w+lehFvPslzfn%bp zfNd4B6--fUfo(0ZZ2-0n#P$HPN%Xs{0k$>7wjS8lTeiU=woSmciP&}k+YVyOg=`Wv zTi|HuYG7MUZ0mq+9kFc$wvEL0AhJpH*){;n2FtQC^sjSl2A0jlvJ+T#5=(Amk*HY$ z$352o%Nk@Ul%m!H%X(tj1T33~r9HAp^jX#=N8dT?lKuaEBd~20w#X5|1o@?M3t(*_ ztX+V$i?H$_mPCyeILx^gu+}10;S{w2ur?6ZX29A^SRD{cB9xT}_BR2>CdSwb7+VQr zH(=~0jJ${;QDX#-Zmt82b%;?!&K3a1M#9(v7+VPAA;ggAV{8VD%^rq)%)1RRwh_i2 zz}Q0=`4B^*#t0n4Tn`xQ5hJ#5fU$`%wgSdh!gv@lB>ET|lcR5=jmiH1z6G$hcv$i_ z+74LT32QH4?Io=Ih$T^D1rA+q0IUs&RWwCy2CU75wGFVg5!NG!CDF&&1X!C0Yb#)F zWvqRGv5zncAcjPZ5jbGE5im9)hD^>Dz}P|<+W})cVLXZ$5`B!#fU%h{wgJXA#@Jac zI(j>+`G3Htfb}V16+|qF8Y^(zauZ-}LabsbYAaxEC9EBQwS%x8LoA7YmrMUdyI%T7 zR+=eA#h%uW9qB!oB)@1Rr@Z#k^Bp^PdNTD(61D*G79!pb#M_y87ZC3v;?IEiGa@d8 z#1b`e;K=4?Al{6`#pRj`#M_8?ClK!>;*Llx(I>tP#Fs5`>|1dD7x7jg-b%zffOrQJ z?*`)CM7$q}_Y-kpB$lX&1IIqM0Pz+imbd(NAl^>IyMTBX5kHQ^5`E$;Kzt=eoH<2R zu*5OuW@$|FHelXH%sYX3Co}H><~_uG0GJODa}i{gsF?%DOSb~^R%DLdIPL)F9ptGCfg3_;6 zsg?{`?3`M2`Tv@vF>FUb;Rq>|Kn00f;bAfN{;7{W&~gv8{1jS#N-dwpmJOlfEBk3yj)KxrQYwi`617s`eCu9N+Dl5G zfzoHB^b9IVgf8-){2i2jw@R@Yh|NMwN*~}1+!7uDg#)B;3>1!$LMc>`s1*WdT=#*( zK2q2Z3j0YR1r;Rv3V(pYA2Ef1elXcjCWpY}5ScuWCK7#%rREIE4R z{Vdskw2-JR0%uweg2h3yI06<&$l^t`kmz?k09_AI*E7)N40Wl1 zT_ox*fs?5FGejqBe+GXghoI{r>UtEq9;L1?VONR%pKuVm9;B|vt3_9Myqf=ie-JsU;uu&QBa4^OLZaU#-M`VU>HhWq_d{THh^$V4)d{jX z2Uh3EsuEgB)K-BLsRzO8AXyy&t0QD}9ITF$)hlQv(YHtds|2z-3|5E9>Lgg5B&*NC z>T|NHj8+o0Rp6BBA+S0`R!70=C|R8Vs}p4PDq2bOtrS=(vN{D8r^w<9u=s*3s-T5L zZ4o%RdKfGYlf^NxI7SvH!Qv!YyoMGMeTzh}NFPxb! zidGV}Rp2!15wJQ!R>#5WI9Z(nt5amv8LcGxUDJbAda^nL7H7!fJXoA3i)v^gQCkE~ zupR}AqhxUcEKZQcX|Om=7O$g)MBgFCi$c#bIsJhbGis97YU^% zqDa&zfn%&E0ObUsoCcKBgmMm0&JoI6h$7KP$pk2w2;~%@oT35w8Z5phi&|(QQCkF# zuAT&olVouQEY6U{=V0+US-g!F5`BxzV3C6fLirLl=l!tqK}ddP_hxqIY1Ez?{kIk!Qy+exDG8OYKy=r)w5u6mMp#i zi!aFH0$5xii}%q&qTeMMERxCM2k80(b-f?%=r4V)1D0=j-dT`xe_3)J;%==!zaRpo>xIi-nw&tw+Q=6UFKo_bw`UKgp?x6tcb>XjRM<+i<48oe$Q;fXh2KD{Z>ZJx(CT|?^%J!EiCPtaRs~Eel|PN^#jnuoSL)ROdr8#20*C*; zgY0>{8E!AdUCO0L36uF^{Wf|dM5 zE4dw4B2lj-aI)$$tmHDS;DT){-q|( zv57?8Byh~n>#Z|9C)oWBWU7P5xr)vXN=~5C~VpWN{ zYTyXYRj7KEs{RU9f2FE_K-E8}YH6rinyMz=flHOBml`-Aa}Abyjh6ZwEcG{9>YuRG zKWV9DV5wzzsjYCS67^C8$5VcXrTk7y`3sivm%o(6*7zq$)PGXol*S+MC;dTx(%OU!PSm96jlm4VX=^yx${-HnVPW+Q3>OU#)y#8PCC;df#(!cO0{pc1=rwr6$l)@4}@@ z)JqLKH2x1P^&eVly7JMbq$>|gk;kO|gQfoGEmfX>SFlt?OKpcsm8h2*cyjw+Sn9vD z)C5>+0xdONai~&U{+x^{O;c1kIYAx!fuRzL-;^~)IwiuA6KTnJ0!y~Y03BCk|pXT2cCIOmmie!`x~AJ zOHQOEE4O6*@Bb>Z;ASZ*qf<__${AqE8EDD(;*urmB?lf*PJksR(2~=`lGD?Y6Wx-P zELW6eg)!x)Qx|QOlVHh7wB-A6$rAOF15XqyShAueXMiPVpd}|{kM2@Jc7K=ByGnW& z(#Ln9jN63_b{8^2rHoYReyk)>R|-7rn=UE3q;yICk`keEB2`X;%1KmNL1jgiGq}o1 z>dG!kL%WNvwB5x_P&pG-egG>=)RhCz@+Ls#1ge}KDyOH)8KH7Us$BEmC~3`q^*U6! zG=5)B1fWC$N^(GYCX(VaQOnIlMmrOk0Vp#8J%~UO^}+&=@hSjP1e5`QG7wNE0Lnx_ zwE(D=1P znE@y>0o4Ye+7>8J8bBEUC<6gyazJ{5G8vwP9rAO@jZkJgLRmp5D+zT#A&FWj@WgON z5XeXZSwJ8Q3Dg0BI!55h@Fz}5&_9X#XLkLSbe92R$)-uQT}9E+t~J}qypI8&kpso zQ~gJL=@GNf@sGo)ECqw;Ys((GyzuwfZ9Sw0<*<5|S``O~V?|!_hWV`!0 zpneXj|0vd%sOtwF-^~j3vr_%+P(M4>uLt$(nfeK_zjF`#{cjfNpN0A-yZ%bL%l1oM zyZuhUZhubbpOgAOhW#b#{x9?NXM_IPsDBRVpM(0>hyL|#|JdJH2l{7){#mJicGq9; zfA;wPyC04!hu!~N&_5UT?}+^+>i&VpaFd~bGWE|1{c}?P8=(IUroYOY#$Tjl1AuG< zki!8eDK7&ceeD1^0y_Y?0U$R4JdOYoH9+9m+N?>@JHV_-{!Mju0Lo54xd12^0o@2d zH(H>4X#gbyP%;7KbU=DSa>gg5g1bG)WhW#L0OcW|ClE-Y1`0fIn+<@n5l{{Q%0WQ6 z0Vp>C-2^~4S)iP00A&ZD>;#m{0V%c=$FMfRYI) zCjjLnpgaJShk$MdpqnjFt~7vh08kDB%I$#k1m%uTP&GF}dF%w`1E72a)CqwkYM{Uq zx!D0II|1bapj-r$7l85-&@BLTiv`M(22f4_%1Jy`~>tA z0!h?Bfv0nG08kDB$_+rd2`C=`lr;^YTmY1dfbu#ZJwbU5kIJ2pqSCn; z%4cV&01y=*qNkBaq9zJFtD6&uaw1Xe1KT`cl!uJ+gHe7mx($qOvqrJM>I(fN&kaVo z$ta&QQsN^+Bp|UNQh6duW{eV_K?8}}An<5zE-=W&26@3CFBud7g92pG01O&f1NrDS zXpjdC@{mD(XQ1aKe`HSLzswdebCQ^X1`@SF;E~+iV33;)@_|7}g$ST102C#F+X3Kq0g&$Qu?YD)u7XgxAXP5nDl4fgLm>_AP`J|e!tf$i zlBg>Mo*pg?l?qd(Vo<3VRcZ>Ano^}gP^l1AD(WifT`Xz}sfsE^CAobpX5Z^CVJV5a zRN&F!B2cObl`0OUic_g(P^y`fk_Xfu3;#$f3Jtc(`B@C|HCF7Iy{p4i-1{?nwRkO_i|w_X^gN zsOtqDCoTr{ic!6iP_HD_YXS9In0o5g*az%cpLpqompgV&Jz!82>J_DWC0sov)nxyq zO>F<3OD$-3?^UcPQP&GRS6n11ddV)5+xdhZJLG?;Qz0y?g4ybp>|EyOW>J_JYrCdEF z)ns?2O>B3cPc3M7w=>q0sOtruLoNyRN>aTtP_GQtYX$XM{m*(Opk4{8SK8InyI0zj zYn?i}s*K&e*Rh^NT`%xBa&Z{m;xxRapnfT;Ul!_@rTVR*err=d_E$sn&MgV$OH%nV zuDp`svbWMTwzn^&*0+2629}qo%LkrWE&=6BQ2EkOzBH9D2j$CA`8H6#&HpH03d)zF z@?~9lz4K+`JMTUfSLN)^zlr4~>hgidq{~3LGE}ZSlq*l=?u2r8{*Q8{p+nVyRGjCa5d!gg= zkppjKpnDnWUfy-r8(TiUv6h5rg@tb<$m8+)$9O#h}|XX?tw?|D?;~*)V&IHuR`6cL-*>`{eI|vzv*5+(7iHr zuT0&mx$a7O%f3t1*uKA*+TQN_N7!AW?jCrSzY=t>MBS@G_o~#r26V4M-5-GN518&s zKljw@PREGMMseU!6UybV5g!(n9 z{)15eK~q2WT#sMADwMBEl0=WvQDF3i2Zyx6H+t-BlHK~0a*Ir3;*?K8!x8C)) zTi+eqOVsTHr&DS`d->-gyr1*6p?z&?e;u^Hj@my0?H{r2^^-b&`&!Vx7PYVI+Uvcq z8{d2P6qCBn?tKqzFHyG-9CWD(?Q2r|I?%ojwZ9(PUr+5Hh4zn{_7wwjUmLpDrta6d z?n-*g&P!Fh^RB(!`JUKaqV66zF;fe=%Rk8C?R;J6UYEMpgYNaH`(x1kG1I+DpnDzY zUPrpiVrjnvgimF9gRhefJI%fs7rHD&vjSQTa=_~OzV}@_I3_>V|R(V`&05~dcV}yf$nvv z`}NTMdg^`ybiaYRKMvg=H{D}@qv^l@uY>N_QTO_;yWaQurnxwzeiE&2ush!e+e_5# z1IK^rLi@VZz8!AI0)V@BnuTSl7g7!C2`zN9Olcs&cK>K>oz8h6I#6$<(ESGLelv8xnYwp^?ww5c#)0njp?iJoE`QH*lk2Xe zx9q%BweNY?-tK#U>@HDv51ikr2i@yY_Zy-6jnw@X=za@ze+s%kWx6*CbiV<*-$31O zcHQ;9-yGlf_+u`&*nJ;>-6iVofs;A)p?iJmeiL-RiMrnk-EXDtH$tTwv6B2yyTw&f zQb)E^8rbc0rR;VN#7Yu%rNCjE8=%q+ROx1@bTd`D4JzG6m7am^e8y~N$G~>p>bmLe zy45smm-?HDy3KCaAnYblcMF`Pxe>bENZoFMZnsdk2GFembxVP6DW+ScK)2gmHzmDf z-=s=x-(F2^XZLL|c9W>Py(q8g{ph_F)_yCky&a_>XxZDP7zm3-32-e<+*8Uu<{W-Jt+XHKF=+>@e-Qq4wweD{9 z)_o|hU7}w5%k16&*4}{D-Wb;2nAUz9yv1+Bx41l|)W|Jab2o}}$L~-ZTkc`FWQlso zfg>diVaW|?$xUF%O=!stV95<=$&KBTW$`g(S)o;Si?+(camf<(k^_f88o`nq(UNb6 zCErdBwRWrM*qmV$NCI}prXaod} zh~Rc0xSa@^13_~lcm)VvF$AiC{DqN5$ofL3CsU%|*xCdLnh-%VN1&v>Oo24EQ{WKn z6pTg!iJBmA7@{!{G$w+kK+u#3S^z-{B6t-DUX4#dt2CzIb|AQ&2%0+rJq69V~{|iCI}pMXaWRHh@cq|G$VqRK+uv1UIT*HgaH4>tSMA(N|jr<%1Y|Wu1iC^ z>#nrj^|4r4qOKe`+i*KnzMU#Jhsw>V@*Pn54yxQ4DtC_Wdh0ZHy%`WRBZ8KWK<|3X z_^!JfV|9n!^>IibQ4<7?HZ%o-rbN&J2wD(9D9ym$73alx>DezLNln;j4HK+N-e2UYpB$kD!l=_`bKKz25rEg4H>)%25%YzeM#2}bV+Xs1}({; zwKGuCU&cTh$HpMxmsABi2NTgiqBaPeMrZ*BEy$o17_=gTJHg;iGI$FN-ipt`ooUR$ z9bj+=8MJW*dJfv8&VhR#N!@AZU=kWg)CPg`1}(v$B^k5^gVtow77W^w!P{W)c4Q8; z0?k1yFldDa@|(e(&Ok|jnFDF;=D;b~Ihc$F6173#fWjSMAh#URA3P;fR2wj8Lk4$& z!ChqV4j8->pM$n(%t31~XiWxfoq?W%wnjj;iX7rociBOhf(Q~dLf}9{D?pIjjwnJY zfd+&-385Vzv?GLf0pZ=qAZP{}gf@WCh7j&@2uc8C5TtQz5LD|3gPnw_h#*lTs9Fj9 zn{8`gke|a*hSDjjEikkthP#2`Zen;37~YG|!d+?1!kxfyCo!~h40;yYMP|VrzN=^ehu z6uUR|$DX>^?5}DI#pGQTEhfKE-VMd>regO&vHPglhfwUp$e!tHv}f(0SUW0quPdgc zl0%>fgz#-Tvn2iJy4Z)BA!QDV0kC;aZ zV(0Sj1B3g>;6X5WkPNzjL6@jOmZwr)jDA>gF96(201r3-Jp&Jz`uC@PV5J_kGcX4M zBpQIB0f2h|KpwmG0qzHY`w5^u0JJB7PXOQ(3m{Ll2Z!K3Fu0El9&`pu`pXbV<=7Cs znW|uiU@jU+GzP;02KR!2Jbw)a@)flYfWZS~&;blOkU>{4=o&Tfhv0qyxSs&pI{-Zd z?c+n>KCe<8>=4XD0Eq@*cmUu&0Jx6<9t3~~3E&|Bc!&VH0YEnkAW!rMhu{G)cz_H# zI0Gg9WeB9Q9RjCdhhRP$NHhi`0tWYk!Tp|rTnXBPL3=WI7z`dJgYIC^J!;?&!Gi$s zAOSq&0Q3+%WaQOr=ix5Df0T>+sXb%AG z8Q@_6c$fel1AxZ}pcer2vH)^GBsd0-x{gZv$@WSmdp&S1?IthAjuK7BF@cU9pkoK_ z_y}}-ggSPFjvc9EZ|K-N+R@+S$6P_ZiI16j52XIgQyuLlF2RBlO~J8&f)7E#hrELF zQ}0nI_$U>8911>81^Yn3KGA~Nf}l)DJYvHjm%HQNKLy+l)>NVr<{S_=%=i}V-W%MwB6`c zXduxTTniXH4hD~tK_@WiL_CHEn@sV zpJGR04I)T12vY+HPXfY|gzz*VJWUAC0>ZO|kcbEpeS{%^FvKFrLBrrxA;mE$A&^;+ z&UzM}h(Op`Sc?o24a2kmLnmP9L=4XW!!yM2956gb4C#?UqR%iC7=}g}{HwyV&OndC zvqs>-$RIpt2VorwNHhY|0|HNhz*8iU0s<){@H_}SPXZZGK%y@&3=>*^1c?S=MgZYyKzN!Eo&|(w3E>4mc!3a-5J94kFdPtuM-lun zc-{%c2JRk4y+0}4nq0y6^w&w#))B=8&vJVydAg20O;kP!tW`T`?BU_?}a ze>A+{43zYjDUix`3Y>zSf{kb((HP7M7^Hwf3K={P2G5hhOJML48Dv5OiN3)|Fc=v% zpdSn`Is!cgFUH5f{Zgr3vSY9b2_zbVjHTrr<~@k~ED$_P1TO%=3qM-lw1!OKoSkHO3FF>p^6saNb6Y(W8uMqqJ3;CT>uo&;V3ftN_&RSS^by7b!uTkHe>Ldr1oRkmj*mh7OHf|7W3U4SBpQL`0fCo6 z;AIr3D9j-68VS4s0&kE&4iu2+3rqlk2~h#Q8ocfdl=PP=kji!noPwQ#ooFD@7_0~w zyaEQVpn-fw(isdolfj!{@Fp4LL<5Pw!9*~a7&V})!5fZ1kHH)9F>sed^`;$zT}U9& z5UdOkyb1)b62a?0@H!E^1q5#qK`tba=o3r=f=QO3S{he_Hywf!0GR{nZ0Eo+*g4pZ z2oep#ssO@kfbbe2ya5Pr5W?Gl@HQdjMg)mI!el_097XW225&h5JqB-?{^}X|_{2R+ zq~5lJum=q!8iUmVgU(>knGD{6j_**%JlIj9-*F0boD%KG@AtP|OC=3upQTc4pH)hv zr`_qj*ixctxhBx^b!hpzw2ZxI1$jzF8VA0O;9Y3_F15~!ttI-cr$Xzg(bn`1f5(;9 zTlDYJLg-gE&rQf5{`LMJ^zw|UHJ!I_s@|&ou5J|IDit(YJQ*+l~GV8%s2e*9RKE1&!abjbq5R?GO97tz72adtcK^H*iLI?*D zL83v}6hL?v5Z)z(j{)IhLMV&~5`Bc(fG|6X;J^Dnasqk`J~I6uiu`LpAKNkb1Oz@I zfkP-D(Fkk~2)qXZ?~ybzMNmMZFE9rL=2(H6X^g?g4nYZkjDd8Hjlp}V40a5< z0zy|pIE)Aq4Z@ZH!ux>mJ|TPrw|XDZt==bq^a&vqMI?zn(p*5A8%6TRq>B^MW6~u) zCh;4+Pwbd<1EFptbOePY8lkNLp$|al0}}ceggz#rt{~Kvgo>e%L|Yuv18=<CN16{v z^P@=q7=4^Q`s4Itda15XP>)&H_?X3SI=k61>j8p2Nbnd6N;HDo1A-rc;726*2?%~d zg55!|I|-IRL5aTL0uWqa1#71U~xy8>cYLhJ#EJqWQRB1-fT7XsqKD55`x-JOsgv+nURi~p5(4?AYPK&Tf9 zoj@UpMrdb1s0#>nA)#&{)QyCCf>2KqDuqH4eW67lw8#q8Nn^~q!kBfXSL@*rl>o|^ ziJ2WU$7si_Hz4*V#FL09(ID;$AbtXfpAceqKB zOQJ&jn^-Srq{K(2NJ#7yIVC$qeZi6O4M2Q6DhsLq=uM zNTP4F6pWTejp#SE9`Hu&L9f-@5$ZAPZ2%umePBWLv18T`2>TJ?86=cw2oD4Zy8~f& zBJ2f(y@;?c5cVa)a!4rACtL=E%Pe8tG_Gbn0kJ2&S|5j~1W@Ks%wlu+ek!A#!~THS zpAgR?qC|suDS+4m5PJ|}Z$Ru#i2VSuA0d`UM2SA)azI=jMf9&`eVvdVv%c{$b2k;L zpB=LSAT)r4&Y_S*BXlGn)Dwhyl29KI>O(^PL8w0oRX`z$zR(H~S`iiEt66WDvflJ! z{hXl^KbbNivs302?UW4!!+~V@IT}hdhL;0|y}+;+8TJLkzGOH635MKqM?8?FSy zl~F^w+Vyutdd&J8phr^QhH8Kvvq3;Kh={&GB8i6RXn?3U5cMXaen8ZZhz0`DKq9Jy zL=t_XRY0`L5?z^c50GG(@3O%l(0>LdTq~U~g5s@Ssq|mYE0f01skOl+NU_u%ONW%!JIwDE*k=6s! z`Y4irwHoS#^cW3|k5MgmH5z8eXaoq2Afc~ONTLx6oqHY#LIX)?2nY=!q2VAjoP=ti zkVIc-0|;%13h~uwm@`u1BU2&2$2Q&(RMiJ1r2qe(}h0a6|2B5(NGz@@- z5zt5g8c9I45J;jAvXnZ(04kyP^;5dpL$AaTna=Z>5 zCHjurz;T;(te?ikZj6(%$I8bTEA^o~&g6YaKOUII6Vp$~B+)R14xWzyrV+$68kk1= zOo`VcgG8TUJ1}gIGWZv?Q7}!T=%pq=@d;8q_Dxm$V*j9nKTC-}BZ5TpUx&`7j|7B~ zgfIpW#t=e1M3Cqs>;QxvQ3Sp!jRuC%^kNf%VWKd=!%2yku)0K3J#=J!6jUEY)yG2h zu~fZ2R+s3lM(u>^JEPUOLBpkEZ4m%SZ1%CYJYl zCEkF|C3^pb+6B#b+2%K-aRC?$-N(|aO@{81srwb|F41(K6!>^(40Inu-6ui!N!0yD z>@Lyoz8kvlj&}Fo_2Z!UIC`mx#bG0gORbD4O;i7MD>cdf!ZihirjXE86q0C!Lg(Yh zg3wqJnhZjdN$4gNlIRQV0iiunA-*Jx2cz-yVw0Sany7!_5|Wsb{G|1MZJ!E8Q_1KW z8c8%pQvy>o4vfZ;(L}g*O!TiEY6=)mA;X)|P@-?R7Yz4C4e8o40SG71YfW~9`WLdv z@iEKney^Wm$7~u9P9wr!kWiu_44u6n4}{~1a1szsBEqRaIF$%*K|+Z>;XWYTX9;gi z<03W1At?cpU+l%i&Y5Gfzf?>Ir0In8Dbw{!sf_1jA?exW&q&~BK!>rB^tue(f)}*IFSga z0O1rOoDPK3iSRZgl;{(F285qQ3Hfq284xGai%oNgN&saHg)BCP316l%+BuvFh%*WC zcSMwE5N8Cgcas2d5+P0n#HoZh0}y8rVgp2!=p*h2#Qjl3y53Cz!zuJy)19Fn#ObMn zn9g1BX4pZT1%|W8@DDVUXbfit3@3x(WHOuvhSSJ!CK%2n!-i-m(KkE*h6k)+!!#~< zGn|qVA(=EWag*kp?4->GrP-wPCn`xaN};bGm;y>uNNGAKO(&&Upfrn=8ljRzU+Ewy z9gHgZSG;L3Xw&GWW;#MWXfsm>&Hczwv+SVF0m3;%_!kmNG=!nAFPI91Q;Bc}5Y8aN z*+4j(2pc1zM4#{w5FUyW@)d8ELs9}Hb0#Ei&K#4Sv$=pYmyrHOB#8!TQQ+M;4Unc0 z(o8^_Nl0@5X$~PZK_rPj(qTY497Uol+6)-98T4ASouMAI*{Oq;=&opU?4Zp9!+B)* z4;o4|hM_M=m=1>1$#51J&LYFPU^tfyZ%0FkzTputJYo$SrEx`@6QS zCv83`%_pUQQAwgv3Vnsb3{aXuO0z*}HYv>mrFo>(6qO|UN=HHIXjI9+qRn+gdXVNC zAoqh@F%(Kk8A&U)~{JNg%XeVtUC@v($bjK1Rp8+IFG>V}wX_y6yvq*6+ zD9$Ct1)#Wq6q}=>L|^eZC?1b0(lu=kAkLxJn(q+xD9*QpDsrA#EwH1w2oM($Vge#c zG>D<^d6*4|vk7q?AkHJig@Cw_5L+OkL?7`4AfB*@jnlZOEpSXqh-AjZM9*4c1j^3Z zVqjWKObVGK8m7=!LCgWBIm9#{nC27HB4AoXOf8W~qR(^^m`+BS{HxkL7`1uyQVX4- z9<_y$QFC{?YLOkaC1ALO3=`2%qA?78m&9B!oJ)oaz;FQ>E(XKJWOxS}O7sm+f#IpB zAz$_8gW`O8u|-Z%iJ(lPki{p_Ioe5F3W`ffF+D0uG>V}wqnHPZ^GI8l=#-Rm=yZ`Gm9x zkQNbAYebUhBb@=HGZv{y8dt4_z_gHFZHZ%2LL{>!Ch=KvP zqLD;n6#90IgUXcB$2 zF97Wei*|b&SE;4Iwv=9Ng<}%1*ldZ3hK=3lJ19F_tAS}XF=as}iH0fk6&*`}X$dhc z2d3r3)DD>>`b=K})0a^u|0=Z%jF!<$t#n3ulvWy{mZ^U`r&ifPS_49BNGK}`Ni;$m z1E20J1)-%Rv;u@ykkH*IB+(Z-4?^doLVS%{4o1uA#a1~ZB|b7oLK2&!XH%8z6s-lL zwPchHjU*bQ&=-6x1EXbRv=WR~lF>bAB+)mz07e(0Ms$T*0Yoe4wN^VKJw~hJW8`iI z)EYZR>wst-5hWv$L_-w%29V`Iw48`m0nsWVx)+Hg`b1v=(N~tJX&Tp~m4LJoUroLi zXpKWs0wi-JCU%Y-lbxgWfV7^FvLlj2gR~{^URwc3D+p;dAgv~(`w&T@k8}}`E=H03 ztI;YDT7@qqLTjCn9;3DKF>-eTYMmXU4Is3EgmR#eL?aaXhLDvYw339@fY2Hex*vrk z`a)lW(AQBRz8bA_2BHz05~*yb#3|S**$4(3$si{hNHhkaF92Bu2CK+mEf}mNg9p$+ zqHpjG7<>~opsURq7?U;hTI(H=9+UM3C}DT%-?6FyMQRpi^R)f)M zGFk^l>&WOqG?M5WeG5k4TBBxZTyEBa(pq}84NggkkPMQT#0DwhyHqDTNt;1wGb!ap zC5c99N8oz129(y2(t1!@PfG1kNusax9VmSlRr0Sl>wst-z0^iWqz7qZ>L9rfMARlb zNLzqt3lZf(B8i4*XMkue5UnMm4M4Pkh&mvVM4#w;Ao@N^#21`R4nYZk%!yQXbK)56 zoNNVzt%Q&l5hNOfT>*r3fUu4bHUh#%LU;%fB>D(H0KyMZ1iIpEb_RM7Hm44P`^l`f z*g@C^2HVIW9~wwB2BELnSPus4$zT&0Y$Ah)(Lkba@FN)fXbqaDaYfk(Z#aPob04*2c_+#lpmEO8l}(|ZEOIg4WzUgls1#nBd8?NSNaK*eu^sjSCmaa zw25A7t0U5bv^8~*+z)TH%?{EIAlgAh1&~OhAvzFvGi?N-jY1?BdUZseLBB_~I(8J< z?#mXi+Co;3qLoD7>SwU}*;=(oW1=<#*JgUPZH`L`l`L6s+(bDryYijDwUf9CB9}zN z75d7IO~AE@CTc4vZ6&40P)VY%bP1F$MV0)C+5$vd=%uzhB0W*t4UqgMn)-K@YKI-E zU0}3}j0&NVL}L{C(u~buwAqf-CLXD6fVGXVIwF=tAL}w;UA9;)(-^6(;I)-rZHMzx zVkILbIQreNDk5fQYBzZ8Ca=QiCDC|Y4!i}ofY%n9sqMhDotPd+CW$`N6=1p&W%6fg zr!&wqv(pH)Nm1@9t#;Xo*#iQ5NT3J`NHhYW@4wgz0$WL72MFvSfhSNvqAze21g=H} z__k&{%*l3ov0ctciI2>Qki_QX#Z)CbC40eWFBug@BZ>Qm zlIR;<1EXtEBf9I^?FjUk?2eB~8Ckjh{)#+uX5Y%pf+D%YTA(TWP>Q{jJ)ra!0D!V{w7rvY*?R83eoc0={ds06o zRr~BXeFjROkx~g%l4z7d-(#^8ly;KR9#GmtN>8JbL|^GQQ2H&RR3?pa+6_><@f8JX zpMw&z*f@zxY@9l$QrU6Z4^aCFsw6^5G*F@Mve*Ssy9jD8K83s8IM6+d%OLKYh*ak1m%sO&f$1gL`qRT`lr8mQ2hTI>O+Jp}bB zKz&M3&mxpWAL>tl`qPK<$7vrZ?W335@09d7?KegVhf_ZcQwQuk9Rj99#8d{EBpRmB zS6l1_roF`U88CfDOwS>cM4#y|VEQY@7TN~TuZgE19KQ84wFP# zl#pm7Lf>Gq4q!hZVS54qk-I?MJ;OSk>5x!wMw(EBL$ zE|0w>n%<$WkN6CFe@49zLhpmr`$g<6(eHf#dLN+w{jlq;_xo__e!HurI%4mK$)@BP&K5cEDoy@ur>O8nl zp42fr4=14a3F=)5drLIELtp7|5PBb^-bbMK5$gR4_Lk`PPWUhKNV-b+Pp_rCJV%uI z&6FoQrG6H87<>-X>l|}FN^E2+z@(JAuJ4vTN>J&*;K`Dtw zYGUBCgu@_pm?r5M039Qs*APge50nT%i3X@5104mRqx3o_9FP(m*-g>VySgtzWJl>V z0G%eFst6>}0ENCx;s^j8A)w;`bew=XBalQNC_MnBH$asb=okPUqt`jLm-I;DD+(tM*-+40wr9OjRK()B=kB8N%Vy>fKUb_RGEd2gV1q$ zol{OoiH?kraOe@56fv?RbQXlpl2CONl4yjc1m0uEKdM5fG-_@ z9)T|-BT&Zu&Cz)~0$%~ZR|Ie!0!TCfp>Iw&3jk*c;0plwf&kt}0Es?8G5{nSfZ7aj z-T^2nFB2eb;}hTr>;zl{fQtlhJpxEH0HJS1I0pdd5FmEH_9X~>Ndh0BfJ9#)I|yVq z0(Ds6f)mgqaKZF%pZXUV>MJ_{Uqk<|see7}FVXZ5eWStW(EoGpe;)dur~V&ee~Eto z9MC_9>0g)of93is=`Ir>bz>9oPO5<2|8JoGH`KpA_Lpe-hrX-e3+Vp^_rC!BFHrxF zu)jpVe@^J1)AYZN`(JeZ_5NRs@4x$*slK-R|1I?Ymipg-{Uw_Iq3^nG%JPj2H=kA1#zK6-w>F*<5N!ibTbp&vl#2NJp&g(MoG&^HHs1wvn;klbZ_13=#pP$B>&5>QtJlIR2F z1)#hJ=mrM*&H?EW`Ytj;?w39Fy&a(+0q92px&?tG8lceE0$c>3iv;v70DVh9=>aG` z0d+$li9S$10Lo{8Ze*bE9gq?nnIO@KPmm+B6Z8`R{X{^wB9KG_6gu($H2{5$K(V`& z??C7~63PHV8Azx*3Q6>Z@`F%*BXkoB{osW32>lQlA$OHlKiU!c8H9c&q1#YMq7e!m z_x}cjzG0#7LFjuDN&=xI66%3M5`CcpAXLBz-ONHiIw2)GGDE@S_ zXFEcd0q8OTHAEnZ1}JpQ|2qKs4uKNnNBxf=^dkvn0-;PK)C+|q`a*?3sE`r5m4$wG zLP~UGgoGnLLe9vJ&=nB6LPCvDNTLx69r6DjgueHLnDtnL#Ks3H3%HiM~)_ z5GrhhZeyWKPDsztrN|7qUnbRMJ407N=&A_CzG;5K1bI>VruoLGCDHuXp|kxzfYuMJ z^)qPwOj=n$D+_7$K`n{CRuRxDVze5t)@7%qL`vpKXyWtayv#f$HbDW2Mj&)-|3?t` z(G!q&)FlwOL;_hsAS(&`*T|)f<5IB>MGAK)n*CUK6hOi>s%kn(UsmvAgFA+TCl8^(2~lTLQy* z8R}i8dO4t84yrd0>q+$Mm4tdFO}*Q>-mk8n-o0PryXS6()Ngk8T3|hire5d>`W2{m zh3e&mdO4}yAgm|RuU87{l`{33M(U}C|J{@|Mc(JXxq?c{$^J;9G2ofp=f zm)1QD*DcXscR5&hIkWDT(RJT$*WCu!EzzudSKx~G8?5^`T6aEJcRpJ8a9p=Uf8FI_ z-Q~@??})Cusa^M-xNeDN-Jvthzr(tJr*-Ftb?2vbkHB?H^w(Vh)?LA@yH#}E&FmW? zT@CoSw}x4Dx;FCP(#>*P>?qOv*P#>1e?Z4SsAB=>Sb#c?#EugEjuoL}Mboi$v}1GI zF#$Rz*p3y09q+=95>3a@k>Wq0J4)`zV_!o6ds1Ti>gbIFxLSRsc3`V1YME?~kgF$6uaA(w@rJLmv zb}cGXiP%LwT?y$W|NljaDJqZs$z?9mKBiXt+Wrg8u=o ze~2qxf#`IlE8v$+1kOaCGjS|(N%UW#DsWXbTz5seTDf;voGXjwQkE-S3ICTal>xXi zSgvkCu6vP7qTvc1AO07({w1yi;7TB_^uU##xW*xuM4zh~a8)y0?V?<*-J3B7Y+Vlj zl@jBeSv6;(!mCq!+B4X^G^3>1x`hr8RDGDnlnRW`aI4|z?sQ%t`2fOfSeKy zXXxy50&pe}XL{gFPn;QnGb3?ML{5o5XHDR&X*lnVa<;XciNKjioJn!c?3yzvGM$ZZ zIx_=jX3Ke7?2=12oDU+WM8g?6G5oZSA%s`x(fHRZNsY=d>PJhW69%kYs?-06WkJ#lA@bLY_986(r{ac2SUES9@dkh?u{OElb}qtc1Mok-kC zz@0?gnSnbqahC$_Qp7zOxh4ACwSl{~;l4l0-Oh4n0PYOLoyl?QPebJ1Qr}e$iriJk zZZ-8MLs@}4tL1(!$lU?CB^vI~nd|hxou0Te0(VBAJ8=qfN%Xnu09PHu^+1&CZp)Pf zTuH>08Mx%$GS21hDwW)7YOZX+mCbT>335GzToMge=;U<<;L1Q;nSd)3aZN=oi9T0d z;Hqo59*lC`W4ST{S4QH>0$g%$skt&mZiAHEYHF@z;7Yb!!-HH8BbP+O6*_^P1YAkP zl^M7)`&=qph3K_0TLlj*aT;<;^!^KV9dKS}INL`#@3ownfHM8-a!NFup<~<`fioj*8}JEhOoWPmWa{dzJd<;1y8qUxu z^UT1RnK-inXEx%@0h~FAb0%_1^f~JTXMMx@aFp`_%b688vl3@^;FNpM_;kA4ASJh= znll%0=CYjWV!yl6eP>7HlxR3Zhu5fE?Bqr=K8kTWxv$iAxxp^CwHp((dmQZ~npK1j zxMu~stYnuRMlm~$VlJ@FMYgliR-$ivBiP<(Y#)uwV3&0AF|N<`bor;XfQ*E?2`dAnJ{w#W=_J) z1DJUTb1q^^^f7M+%$p5nN5;$nm^lbDcO0{@#>{Oob4KooEM`8y%x5tR2QfP#rbL4| zQGVYqo%yMkUhJHDt;q#gxdm=6UppFvEC26IXPGZ$dyLd;4j zDlcH>MNBzgTmUc&5avR}l;~qN0L%skvlCpb!`oB7?6_qT zk$W~JH*)$WxCn3+v0Tf8T+bnwM8g&OW`MlFm6x~*16N_eXhoFE_ozMxa1+I z7}qn*l^?kB6IUVNl6$i_m%A%da;v7fiULNHfvYHSEkiDeKG*GWE_tp?xa3K$7}vARRS>ueB3JA{MiKCm8!+uv zDC#BmW7?}Yconx^$6|k-Lbv@dqL)PDH7oEVt^jxyAg^NJRgAorqnAYAt7+Uzo+lG8 zd4eqF^&EQ@0vWV-qiVaxLcdJbM)eufpghKYWV;m)u3g$1BbyH&vReByg3q zT;Iq3K7_blMlOklEA;gQg@CINag_kB62!Fzq0iP$TZv~Qdhk-H@OTU;67Dr33w1-V{BE{TR~Y2d0{6u62KS83oX zOwq)s^HA-WjnE6iB}I7<*` z={RR)%~{%VmWme;IX?<=zKNU?4QJ@f7D@tVN#ZO6oMni!JaCpL&JD;Z(dWD~&MA-N38y@S z7vt>AoTY)YG;x-Tb5_%wDAm>}iDba9-zM7#FaF!y@vcOrEI4b~W z1>)R@oDzM`wsB5*Bu_ZyA-ovp>&#gOILi=c`8a2F%~?J&o$fFB>~vNF&PtXuN9-@T z>COH&a!NFuq3>}h4V#jJLJW?lI@(^8&>kZ~A3tVN1t3sTs zhUTgenLdxJGH_M4T&06t?;w{%!xj2chcdubhPcWDS9zaHRf6fOMANq!IVJj>?c$vB z$eeJ>Lvk_BH<_~>aF!#^ijGr%wkG$E`q!-yk-Ns&t)%{Ss|s*dv7GgTobMv1M8g^S z3W&16S(Z2}0A~f_tPGr$iE|5bO7uDJj&sT*b;2nR(Zx95V$SlwS)Mp60jJzs#yQBDBX`0n z581^y-)7DVz*&JfD+8z8TWZdVk=r08x0;%>8gN##oUa5q-$zb~hBNeq66JxjJaJY6 z&Pv2t6*#LB=QiY&=yTp1=afh8gi{`}i*dfgoE3qyB5_s$PPw<#oRy-Sa;vF1s{?0s z%XupH01*AC`2aa38qUzSQ&a%X3dC6%I4cupHQ=m9oZFF8qR)9>oKqgT6Ha-^F2?yT zb5;V*O2kLCz16Q=;Jvec44t;H*fTRe-Y!aaIS; z>cqJNIVJj>_s2Qqkvrj(hwNgU?=fd(;H*rX)qqp(E#uP}=agGb%~=yTYg*3BLC%km zQ=;MA6!-|E5^z=`&Z@v!l{jkvXAR=qiJTIB&IjV0^2nWV%0qTB&i9$K3UF2-&g#G^ z_m=VLbhk-LZZ$P$E#RzWIsXlEevF(F4d>=N}M%-Q|>+E(;4TKTT#tf8#rrQ&R1hk1Jbp#3vx;{oS`od zsREo;h_gCyRwvF{z*&npcO$1npR;|OQ=Y;TPI>Mw#`z(0Rs+sz#97mEs`@2juT;~5 zu8Q1w+TVKW0B0S``A(4Y6XcX=I744nQWZF>5@!wItU;W$fwMMo?m?gdXf#9Lj8Y9WtC40+(5y+C zbwINYY3@Z$iN5ATp!ty14E!MaKf>+-XlaDm>v8MW5)B?m=KyVf&&ccH87;_>FbG9JP7Cxsp((x}Ay+WR^ z2+u-+XDRJj$XcBt&!Xg6)Oe$4bn7Bil8oStLZ6QS?v`sAKh z$n%wuC)Q^n@+`!j_>;Awfhi<(WO<79$owX_iNV$NwlC4 zEfR>9(V|7H6&eyPPNKz)Xe+1ayDW;(7j=D3PyrGxAVmw4Xkj5*j6{nG(UUBSFf7`d zL|Yrtlupq?BwC0?)vquWjg#tq7dD`JFF(`TdaC`X-piLD(h`QWr;~IXlOps^ZeqNfIk* z#CAEw#k=eZLWrGaF@#~Uwj|cph((-YMM$g&i>XCcoXD_~ z)MQ1iU5|&2r6wyyWTgyQQuQ|@#545-CPV0xxjyKqFp(9OWF?8Lq#!%PWC+7#?TDu}v=J-p6nl@w5c*=S&pIkXVnsq?nAK7w zR!WGSWif++?6=Si;`IuLd$gm|07Fm4r;$erV$;uE}8ADdXNj8zm z5c*`U&pRqgWJM)eX(B5v$j&ht!Z2BTB5QBR<~zxX6IpR4!y+q1V%YQri!2bs9#D&w zC9$$bEU)^T4B~D%iNz55Vy=%gDn??(q*xgeDwS|;bE7j#mbRbIU`okDK?qK5c*=SPcDOQ@qN(-@afmk&yR?ZTO@5ziiiFPug*PWteNVJR) zEgy(h*P`W(Xjy9mVni#EXeA@M$tgOWMG^XGKp3;qF0=v@3SaEU)1#>LuE*`Oh^=K zv^iV?l( z6rI7M2z^o4=Ma@8(Xvvs0*O`-qLoRsvJkz@q6ovHT}ia75#8k!El;B5g=nQfw3ZgF zWUbMVXjKxeYD9lhf2&jM2R~p@gubZjqln6pXgMibkwhyB(JCZbMTlNuQG{X9ZY0{x zi2mgitw5p`AlejvfLA_E%-etuG0FGeJ6qMrtD5mjs{RJ3@S4e92z@WtXAPAnuks-; zJW5s~uS&wJDtT2EURT)*Vc4rXd385lA3MD&l2=8s0;>~Kb;Fd$$@C#JA@rGCpCMF% zm@0&r@X%M8m?{gVYQ$7cFkNFNgkh#0#MHwuEp#$fBBn}$scQU=s^7H3Hc>CTxz+~J z!>&mU3$F@^RuQ7rNwm5Uz0RTt!=gP& zw5JjM#3@>tL@Nu?Y9xwnWFQ*fKzi6!YSEe`TGNQOc8bnsQG~vz>%)aAk!YomDAs6I z60IskYmjISA$o&F5r##3k!UX?y2L43g+!|e(ds0MZKM{hYHfEs>?*ZrEfTF|MEg5M z=ddV3U)1&aLX}Cha!3?wv>J(43yVf?vKYd!SZ@;RZNxrxiq#+yYy-7OHCqI`LM`$t ziM(n=);dK#ViAPCi0eaws*p&PkOL*$Mp!g@ zi^ULz#rl$1Un91{DOR1tstd7NB!+EXum%G$?E17=9TKZ!#7;ZK=CK$;Uu?eP&4p?t zRxKokHCU6xYKFzU+O!61i#2$gMG=NY`;llrBf82dT7yJu2+_L4RM#+Fa5BwjCWJoI z0|!%eVyZ5gY7tW{!BmHs>IkMg%!Dw^)SsC88>Tf*rkcc5Q!v#drh0}cjrv>hVjuD` zGa>YuTp#iCDk;1w6zY;fU7_$DDKu!62pbp&+>zMoD z9%~0@Ub@yNxBA8{gVSvRyCL-5Tp#>Xo7`#(w|eAOPq^J>H-urg0pvEoxUF}(y-IGc ziq%s$&gC`HuT1M&VDSx_0c${D4GdU8C)h#;L+FFKJ|(CY-5+c5{SkkdQink6gh8X< zGZ?}!*gygsXuvi&!DItwP7z|+;>>UDo$AE2ig4HFkx&o|0989mT2G;tD z?<36mYD`>>4Od|&*J9>E=ySO~C#Vi_)e&6viK~8?%WIU|{s{0!xkFgdADI(j=m>8x zaSk?|Tb-Qsh_fCz)$>AK`Ml6D?&>wy3$dZK5JR%Bk?d88wQRtCvwDYZ=A=bkHoLCRA(_Q*0S$u}isFgnqHEj{~Yl z#nuzWzDCRBweT|Wh7!h5gR#Sj(SR@-2#m&Y46lWr`^MJXhd5p*j@J!G6(`51%z@D7 zaDCiQed4GuIGPYg6TvZzIEERH-A;~%#L-Z2G^HAwni`upYh1=PBJ^u?eVk7Ns4by4GRs&Tlfaj&z+MpR=XQDc+%lxpm^f_Fg?9-4q8VZi4#L-l6j3AB?hGV~zqcL$b28VhWY$P8Bn^UpPO|i?J#jfCD z5&FfhbG)c(M8!4|#Wtg2n~7paQn4dVu?L;SzDC8qCg#2=%{}%V8l#D| zalBzTMySvK5POc5%z@D7aDDDhW8!EmIGPhjbHOo+I7S(cLr#t+#L+}>w4fSWm>S1A zYh1-OBJ^u?eHhMbRO4%+#y637UU#A*h7d1AgDaSK>Fy-;*b`MYZ zddgc8M@z$TQGG^w=T36>+r^Tx|ocPMWK&wYuU@v}Sd+C$9E}Yl@R= z19Kttxm+KW(vrAZ3a&Q9)kbi=NnCFVu8G7o(Qtj^R`C~sL!qv&ukl+3!%^D`Y4oE#MMf0wI!~$f~!4owHI8Ih-;GJy6og?LtJeH*P8)X z7tQsiwYuV40kgVd#1%7KgPdHOm_En*IUH(mf>3IDY#<96%$-j zh--@By6WU=M_la$SBE&4en$X%E4|HJYVE2#Y_;?@vm!COT^_b#nyV9WbuwH(IJvek z7eb%Q^-(14h^w98>Ofo_1XoAm>L|FT5!W=sb;HTkp19fzuD6H_doRt^!P-W6*otYc z&cxN(a9vQJt0x}nw=x$(pUd@8BX1Jdn}RDwTrt7biMTomuIa=z-Ee*DGZ~ zJGo-S6$6)gty~tbmDlrcyLKWsY{G(N7T-^J*pq3uuH@F$xZQWUZDTitzMJb)LpqRK z2jSL{+&T)kF67olxXmE98OH67)9o#CdrK^{&cuaHSg_0jF6_xPS2yD7X1I#0&l42) z%I(aB(C2b}EJ%#FVuGs^adi@0U5Tr!;QD~LJ}_M0Ik~zJ2R2#3>WS|cJnXqNM|a}r zZa6kNId(7yLZ8F+xgKv3$6JD<8nyh`m5WVMF#AEd*fZ&Jdr-MO zOu1h=%iYQ4BJ|63ee6a@Dz~F3w+qdF7cu+YiKDyV_>ee0G#uYMIl9F;yf5^Av6}%| zgDp@3>{hH_s_#i0Jq<@M^=Xje&ajI)5c(XhPtE8=9GwJ5SK{a@IC>CA55X~uIA$4+ zdrpq-0mo*|(Oq#Qj(N+Oq8Cy0G8BiL6uX%Mp?^x($6a(Liq3+f8&Px<6g`Qer=XZk z6tfM*k4}mn0mXhz(Zj3^^)Hr&Rz`2)=xsP2IXU()2ST62^-&eQsGMG+oH8U=;ODyueTna+J6xU}+^q`sRA!e>OmD*dB`Vp1- zktubiv()Zs>|eI%o`!yvA~H1Q^$IKwYKvZGYSlm45t`b*Zc@@4(}b_ULWa#!6lr{m7!9u_!#)wKn#% z1w!A#_0bP~sn))t)_GLxJX34i{OY>l&-Cd@wf01#X|#*NxDx+x7Vk{iyDKqVD-r_k2@#erMgisP0~&IUW)7`Udr0 z(Dn8;bG(Y@_-(57ZBy&J&RP>Z^sGBt6ro>hsaI|3=s_ky=pS|wR}TM6xc!NwzaaUT zNIo_suQ*A16G?AtDS*db3jG3_hnl9JSqkc}z=xK?0OA>7c(yuuBFux(ue&Jo9AX}X z{$ZCKJZ}@v+k$5S@hmVr1)My6h^LR?`3(1zAuoI>~ z!SuIa+-qWB;PZ#}8EDpo`cvr8nixz*gN;!Er%@s{Lg*W>_BdV(uO zs1GYDD;+|W4iS|urAn8YN{cxw9Y~c9l$8#nN{5+BuMfqr#EXTbTq#1o(zm(NlUyl6 zeONJB=}@Y4sHpT)s`OJ+X>n(zgQ(I$veF^h;{V9s7`@1cs6~#AWdgi8TZtF?a6%bw zP`-1bBx4kWKFUl+ImIXl^6pvUb84aP2 z_EAB4Y(C3q2=!s5B-$`S8z#_3652?Cwvy0R8nn_*w4sEC?M(1GIJCPT5#Wv2cq0s6 zLWwt;@J1WFEKa;sjE7LGM2jb;eQxv|>mk&~m6m!#lGqPjLz2)kz{AaO(j6{zN0II* zp}UH7R~g+hPTgUoJ1n#$@t2B62C5UZ>PVxSNUDw@)iFjjn^QG4t0L4|Uah*cB+oM{ zLVcKHH$9Y4hYHjYggQc?jwaO60(CW^t~RJ;ov6bJb+|+w6`;PSQAZin#1eHZp^i1E zU7VJ5QmrUO^rahddY1tH^Z`zhkzh+Z}`Y^{1emI#97p9}gbd)e1OQvIm z>1Sm6nK3QzG#yE%BiR&>L}TKn`j=|3VbqVkNi9(i`$zppY~#puoH6a^G)>2*2z}GO zYUcsOZ%}KEay`jE#;6FjR`jVv9zCR9WL1RvILGUfk)%3OsE#4kF+z15sg4t> z>qvE-QLX4y9ZjmErRuw+ian=RO>V1V3#wHokm>}Z+R>?+o>dWQEpHQVoh~sdLVcLy zb^TyZ<;c#g%c=IhlTLOe;H0$CBw- zVLF~nu~XHiDQ#11T(#*$GM#8lYdTFIXH$f}=>#^t%%%wSVUE{DW5{%jFdavxk-9V-rjA<38>APh5t}vZIrr4)y(^R%8wyoN95}8girfr<2Pp~OMjTNmCdPKd# zs0j6Oj@M0N33aSM9Z#s^1?ogXohVQ@66!{STGfd*k?AI5TFq%X zk<73U)n;jIGi*z>*%UIHV$8-l%`&kWLf>p5n_Xiwg!(YYi=}a7HcptmM`rH{v&m#O zS(tr6W?vYy>Q1vsaWn4&y>Fjn)UsP@=C1`zC9|oMXF*Vzp=L#PjPyw;gOW)pF|q!8WW38P3!5SI&DOKoO*TWQ4|BYhd5_HA6K0diY_c$$MrPB5*;X>!YRqam%_gO> z->I6ECj3s-)WCF>Hl1orpOL2Tlj-}$w6fFmDKq{9c~@PTpY=XA)*4hVgRXgzuv ze48B*>cbqbE+&)1WZ^K49Ht3}spK#f4(iX_rr?(rHsJR);(q{*ms{@#ARlRv_YKIi z5@aTU%rqc#oFLg41fdUdnP0-*VGxA+Fvm-SDFiY_fJ`Tl=>p_~-1ei&2f4$KD$@vT znpik90;jp!X@+siEuB6jrw@%&+X=2m^6cz{(03}q3+Fp_LZ}aO?DnUU(^TQ~J~_QF zoMw{KOyRWiU)yo#zy5G*J0Fy$lj(F}`a#@Ozte}Em|moLEKv^|Gre=2MW(ZiX*Z{7 z4mL&T53(|w-epsS`Y^|Ce;S!i6Q(oBbcQhfkW4=mrn|^=mocs5G<}~;-xsDc$rL*^ zZTg&TijA8#olT~*jpolD~rZa@;hh&PKoHl*lHpRwHo6aHAImUF^d#?NbGi-{`H|@)&_t+GnKFslI z;e9fFUzpA$)0x6_Hkr;ArhCYAk1?(1G@V6e*r{o=7i=?Z+_c$8WcHCUJLoj~ADbcc z%^t@R`|nvT`U9IG)Q34@?KNigon|v>9nKW%a5kA@ zBd1MYv`w+E)24IDbgnU-HPN*WbFnEx-*g|Z!ynlcp+3y<6 zju#U%$#kYLolT~*h3Q-}ohwXdk<%>U^bt8>uc)0~wwx$Rr+LC@HaX1}PIJi#dqwS(*LK3zQ9FH1P9Gbm z$&+07(LC&g(0BTSoqk~_g!(YY3yfLhG)p*rL{1+Gr}^YGUpO87*WM={H22Yl&im*b zGMxic^IV7gSB&Nrs&hn=P`uqi^{G$Wh-%BBeQVU8CzACc)t!gM~F&KIT&$#kJG zJwm2OjOlAm(|Ke%Pna$UOqXfX1;(_EH2s83KQX2!T&CXUx%T7K=DDHw1)?vqIYQsO z8k_&d<_Ps+ju$?2$$YLb|Cr1_7Uqk{e339eO6Et6c@wAkd@`Re%ohgc%eDDJW8PMp zFDCQF#=P%z*W>L=Y>Ln~t;?prvnfJ-nB#@dJTjdpOc#*p0%7_InSLTnkCEvyWBR(& z^kXvp7^dpUY`%OlTNL1~(71~XZaay)gm9M_+#ycfml+qKkNY~~K4e^k`Y^{Ur1^w9 zU*Ikz+=T*nG2t!_<3BW zC8tk~)8|g7eC&kKcN)Y_f3OomeVF65&H{2;Ae=rSr%!~_QgT`0)8}DVcsMOiz*NDP!8qY5ED7ej-elk}0;O+Ejg#Q(%f+sy1Ctrpt}# zZKvrgY>Lon`WKrb)Q344DK6F+$Ds&L@d~4WQzT%HtlGeV!NtMSCZ*UWBP{Ev>=-z)L79Mlk*=* z|HG&V^>L0DQHu$6u|WNlP(Kx@D+qOkKs`&SXANo#C+bo{T`EwQ6Dl^K8nu&+iv6fY zT}7y?3~Fm9Y9U5NsIk0m-RQ;szif(7ALe)wwS-KU2-9U`x=fg^B-53`^cm^k`emZ}l~g_Uin{tPcJgv}}^=nM^hn&?H;p!3k)nDf7Kc(tF71ghx>Q{uT zk0v-Cp?&gktjK)!n)Q}b{mW6mdJb47p95AA1U7^Ez^*m~_J$hbGlKZcK-_ae6lDm6 z8Y0>z1wCGQ%Sd9GkXT6)E5j1r8d?Wy!s{R!VJU=Rsjuli^|iTAwQ}C4R*>onv8qx<(j~9leS!AStex5b!55DSVlf@ZBB}_B|_iwXSQ5HmMeti zYO-7{EZ36dT45PwON3#|i)4AxShjImt|H4-!t%4YrG91dnUU;f-O0^wxUMJ3^+s}u zQ?dk0BJ?E_H=swNl_a@RNUkBtH9~S7Nv;!;30V?hSaLP#tQIiSu1otC!NoQPGZ(U7}oiWbUqV0 z8>#4xrs(%)x*mK=bI}O>qN{SzYpCcoqUd#0^g2=W1}b`kC^`ujjWAsF6?*Ww;y?IA zK1NN+`o`L}E0H{A?htE9XRXlroYv0g);%l!A*tp>n}~6fVVvn?EW?ZleZ~&VxSp8S z3#N_4v{5i6WhR7SrmMts)i5oPOzVhgonYEPOdAZ-=kfvi3u5}hFfDg7m1QP`KGVm{ z^f@toE|@kE(;Da-Ia$em)@*yCaBE@ zYRQMLyJb0sLg+*N#!wpwYJ-6Kf}p+-P{|nzVHoNP@4r*3Wh=$hPpveHw@G#5^4iM z;TN7muamwYs4pz2_{WfW-3-)Lg4$}JE<2$rFcd-`sy;()BB)IQY70Sa5l|@^3Sqdu zn*?>!KrNC`8wqNofZ9w@n-vs3&3KgAhmzwfvrDB-q_hc2>SgsLysXB9mGxVP*hyM1(AB;&xC6%b zOdhtG`VP2_$hH}>yiT%8Ooq@W8^L6oiEOhV`;y4M6lAHH3}Kk;3xfDUESIfR|5m^L zTrn>_7L53SAa6SnY&Qh2I0-5<0YWFi79!XZCWxlt5)p<=yiKd(wpkTkE>%GI!*Vwh z$7aFtWt_vC87+Yo^Q8j8{YU+4f&cxks<(q2b{L0}PKPS&fY3kXOkN6G$zf~Q!P`zt zVY^rgY1s*3*y#>A-7!v+a=4tfkkc07v@PzWUutao|16uG#I@6Kz3$|y%3KJ2u4T;i zC2@TzxONcN4#AaTMYouLr=P&*lFJ3(z1P`e0fmw-yoPzb|N-xJjL25PDkY8ydq6Hq$|YNro{4|5l< z==YG+9wRl_DOH1|5c*P2H0H-RlG-7pc9Ya@A(erp5Qe4hk<>jSHP89Ly`7}C3#nak zDetg;Z)lgXQXg<1e56YC%h>+B|--9l#{>FhH)d*#FMLDD&BbWS*R>aY$%UndFu^#E@d>Fg3Z zdr4=n&^bUl2ZT;$)7~FLFoJZ z@ESez?k1nz!e<}(>=Ql*$>*T(d6In)hJE&u&tCS4T#R`K2UopaP||<{xD873m1L&NejgW)zpH+bYCmWe#|(RM z^fL7yq56-Q`cuz!?e^+({RsW~A8`G9ss6p9{sUD10a5=`TtC8a{rjo@{i6OuRR19} z_haL8-`muFlxja}YESR1y#d#b(62oe-!b-4?fXRS2dVahqV}h`c7);D4^Zs~MD2&E zcI?aadn;=0<2y1B+cf>&$}y_{n5jRzv;Kx$KSIC$aXk0?ss8<<{zFv%AyI!;t{-8z z{)1HiK~et^s{e?oe;b}Q;tz~wM|zy9KW?fo;jF$9SC7!I{uQ46162J1QT<`6{;;S% z8&{7oT>T-c{*b8tC{=&dsy_aYE}H63Q1vHF_0^r#H|FXQ`qk&>>JL)&2SxQqsQM$} z>b>K+?Op2e+@ac|*;xl+=m_u8zxEj({Tu%IVbVJ+^p26A@p*v9>S1LG(mR$y{YWsBfLMz_YdKFJnrY6*RKbU z8$tDtU4?$b=M)K^GJ+GFf=yTup%#qZ$iTlYb(jbb3&LYWcuWwUB*K$|Feeit3=>9} z5Mk&D?@uE9QxKjA2*1*VCoIDFpH7*(@M$7EZ3t&O314SIg#IG@g%{xw5u$rH3Sh(;L>Vfd1#2=0`C zJ49Ez_mzNqj^Pl7Mi5QPa0tUkcnpUybOiQY_LCoWVfxkIOl$w;VN<4F{Y6_b z9YUY(yAWMMrb8IM=xL%mE$Ge>-8n(`HPL-7=$>afgrN~clQA8_@DWj_Ll`>3`-2cjIqE^)+w9{CnBH&;ENkbed>eHbdy2C^ws( zBeQeD>}xXnT9{oTvrEG4B{oAC9%xE7Ll{0HF`FR_9pNRoVq+w@68d?x9b+K$G0yW{ zFDc*k5Qa|VohPpIg6jftT@YN~5Z5t*Ib7#cw|6>}jBACZK)5QdKMF3}RZWbS(Z zh80S3>0?sazB)mr3PvSj9_lo~HMFsGewERzny*A~mZa3?Gq{ z)ewe`@V+6nZ!9%_mn_KNPkfuA<3#wIK{&@oRGZTDV>!*GufG{#}|Y1bZb6 z8_maX2tz}NreQdQ;UkhU9Kz5M-erQjY{7;0WgQp}p%3>L!=+$2gyAb*Ah-(x?kc%l z6)ySN1!3q4(X{M>FnmOEc0m|A!n+c8@owvPZLSy@^{+Vd8(+~F%OLb+k~XC!m6Bx; zhOc>%WG)JsYb0|`$h^Wb2t!whrehg|;UiM848qV6-qk?nj+VJ<$;9_n{`)P_w^#T9awDYH;(`N729ZMhC}H4?&7;(T6RMizTy>fyCU4K zliPLS_AR-6E8GgR8^X{CqK~s1!tfDk*bQOm2=8Xx&HG+Ic-^$*GO%11mP6>vooBgp zEQc_B&8sALRmj~Sxf??67RlWbaz$7UVQ2)=Cs+<)_=vPDhcI-6_ibEGKfHZw+|<)y zXrs`T-4Ob2x7h75c0(Ax;x%%+Cfsh4+fCtio7`@P-Mj=#Xy>{lbp2>ic10LIA|tyZ z3?Gq>T@i+k@NSXoE#s=5HbSo5*cGAgdY@g>vn#^z6|a-)b>aFgxqd5L?~v;q;Tj>= zh;S{&t_VXTjAmk2gyAC|V^@TsBd~3=XBV3|{pQaixW>0{*yH)XHIZPReQ1Jtp;JY> zvphmAAI+47pL{YfJ;KnLyc=Fa|`2G-^NS{7J^btYdgXt0ai~e6;^pCSV!tj`GlKf2}f1BiQ3;DYw ze^Vdx0&JCgs-k`Laud)vr+B<~6No-B{hmrvY` z_7_jEJi_ppz9so@h5Q|oza!)ml59dDTaslFhDH$0!mCeJ6F_|V7rhVBIp>Nufm+F&jiZDFd@5uB!Vfs^U`|kBq z?(prCl6g{LUY5-fhRzVp#^wmaM`UJmgrOt6AIbbj-@Ki@yu4pX{1+jfgv65w@qR3h z&=>E*;#pW6VR)=}N&GI0t9NaGCi0&Jc`_nTCdkV%Il|BoqS=`oVfctAnH*v02=6|5 z-WQ%p$up_&?9ZMEeb4Re`4oF13=iac^88+U{z9I=2+!o?nOu05XHSHoAw+YqC&KU% zS=bX{=m_rtc|H)H$;dOA@O+y+5&E7J*z;-jL>L~(J@ULKJ%6Iz)K6kJb)UTN3-1)< zokDn5U~hz>Ax3kuH^T4{Pq8<`&=KA*^pNq3**6T7e^cmJnwVe3#3ZMQNiHU408b1; zJu%T6PxDK=tUNOa!$baoX66SuGe6VJ{48eX0nN+SiosmL>fFf_#IGdwd0 z!$&;LGlMX6gm*taGu~hN4Yd1aZVq5i7ys)BW^3{r&CPFOZc@HI;a35Qc^r{U1*a!tfDU zd1?@bj_@ADr$)a+_rOfdQ8_Wc)5QEPCMG3KOiD2^gLq;P`gfXdLwB0&JTnNxL;i_o z<|jEb_i1MCi<$Y2X683BGpT82Qj3|X%rk>9G{k5wo*9JUBeL<#APgPhJtXjl0z4Ig zrxM`rFgQa0p3sHw2|3ssVR#@vllRZk`vG}B5Z=F&_wT|x4SA;#-c{HeVQ7faXW1KJ z_=xQ6jWBeC_Z!_4ezP8;_&rtc5lze^F)^uWVp5BV8O#%d(4Ux&JTW=6LUW_F?d1n8%@k_VqzZA z#5@ucla3}PotT(vJTVAELyYF(i9r}XA}3D_!q5@kLzM{;Fg)f5G&K)+YVe2tzthb8E@tKrnwdYu%sfUj z^O%^K>O3 z(KS}j#p(#dIlO}{EyWUhK}(5 zAoV}Y{b8wne;8=wA0zq4g#2)pN9fDvElS(iXIUO$cuc>M{BJ`35y?Li@_&*1UqU_u z$!8GqHCY~EXoS%hSRP^ch+Hg>Fm#0XC&~Y5*89ZxdLLxe)0297p+17u5&G(X^Lo$C z>IlQ*`JL2%7wUhL>fb{3aZ-I;sMcatgrN~cUu0E;;Uk`9RfM4<@M6t=rw}jQ^c(SN zJ;z_P;gy~LMtla6%^+k)vMfShHqRThp7XFQ!tj_LlI%kv`wz+fBV?Z-*(ZeTt1OE! zG=k_$EQ>I7g!ebO{q3*D$U3`HFF`)rHbFkkp*~S4^x46W6YS#xb`--R^kGXe>~jo@ zFg)l-1p7$9{!6g`3fPPUn^C~lW>|!w5ky~RScKst^6-*H7&^lHhv@(Dmn=R~QT@r0 z{4lr(O+o~dz<&<%1mQm+@JBN~LLWcI_|G#w!tjOuApAcBeu6x-TJnT%pNa4@3H&;Y zk1%wGXkNxg7(U`T#zz=B!t;pJ6Py`|Go#=f!<-0x&er^-_X2Yw3=bqiToJ*QnYc0w zuDZ;HFm#1zKITFgKH_=iLKr&2OOTx=HM?J|hfh@f?^p4>D49luX(lqwBuvM$DMEdj z=udq47 z@DVSvIl|Bpo=4_b!0Oe8{&c)HT|0Mc)$6}c!cRo-i3I$U1plOfAIIg!q5?3geE2;CMF?GOv3-i#3Z4KNg^iZDVmt4#KcVCi9zU3 z%;!8Y`FLUwhD(al#6-o!B&LZ;EG8x^O-xoXF^za)5Qat&EyNRpFnmN_o*0CoBRr2L z#uF2hh$be{|6^j3(!^ln7}`5NO%wBUXku``Ou62U-au=X0=Ge{fKOYmg;o!(Fs)wyOVpss6J~{b&1$$N;ZvB<4l44Zu5JmGGK%c(z#N zy8*C^BG{8P<|RYF3w;9gJJ3haZ$p15Iv}a~Md}!S&D#IzHT3GItI>|-8-ULypP4V_ z9Y^~R?L@vcM6Vb&p5xu>Ue)+Geyl7r<7Ub-3t|)$xf6>lQG--w_b_B-xWm|u#Q#5^ zP?e{&zJ}JbL3!`vm{_2{)Z9}2>wfA?>R%;QT=+*HBM0NlXSbjI+XQFVK@JlElzZw1%;6jAOVnt^D3Q2z>CN!7mref41BKC31nr#f3v{47~cJYZx| zQK2k&*vJyA9$!nDAfU$k1bQX55ob|r>7c)s4*6?o3$ki0eSu!Br6M9&3v%|xW?%8Opr^#Xb|-j~py4A#>rjI?C1f=XqH)r=cw$GFt^ zom1;(z~G+` zq7MtY0IYU`j^Q*sV{is0CkI5t^;Jr*NU%OMSVb(<9Em2awSv99rl+(L%pC-i56 z$vbN%?;QHtK}~fKtqrbq7uV_%RKF7Eej$ivA!?m9epl*{H5NG*pWK&GmZI%Q-9Q-`eXjo=fO|a)bGbn)zrU;UQK;c;Hjy9 z9zR!8f7qY;(KN9n%1SMTZNri*Q_DhC%C;BQW)C82qvwRJ-Mrc*h z8l%-jD;?aM%HlCOdBE^47*0l2t!nB{qp4a?MPuF6mP6H60Haoq0EN)2B~Zj4mX{x~ z8s;6uj|Y<}npjpjY#l480otCiH6bU!Yg>w-LR%-YB$}gOPodEmk)^FNHA@H7~`{t9dDb z8q~a$M6Bkel&P^8`VGNMY{W=Y1?QW9tJKM+YE^5fkr_ihbL|Fr7I_fga-PF!)dR#C z^lG4|(5nHS$QtW80H1NFuqq*^u&SVs;?dw|e}vV{O&(z+YNVCTNNXUkMq1U3v?BWY z!AKimq?v+QzF}thnwjNPW|lLf&l}V;H(RV;eCEoU!IVd@23i_@?_lQon3?N~zIgCt z)eL7V5ZnU`Vuh6t?mHE5-$@-@={*?L4dfadx%x(~A>@8l15pdKHZH8D_$ALDNUf}~ zUIQNY#quJj9-Qx@bR~BL$EpYC2l}Rw-+aekefnegp?XYCg&V08*20alpr4OE1^T+^ zF*T82{Kx1tI7}_2+DI$rljs2vxvw5A)cszq!wnd5zMzi6rjA!k9R*Rx>G%pbi_5DO za2mZ@0VmNb*yHG5*Bdsq2HGN8A62(e%RMblq?UO)bK)N6#4C{76ioFO`C|3sYp5b_ zuOup?S8M2mzlN$JR2O}SBGekHgkG)o>d33&s`$lu70{;%s+)+*9oCP`>M`zo)>v=# z?4gF)7`Ib{Z-~B6aL?_R6PaLGjj%SJ4Aw@wo1@_89KwS2xq z)e7w}j#bO&w7-1L`h;ivc{_?9s^yasH&Q38i5scqGY`F5K6TKm<#We^$Yv3~JgdMlhyRoe!= zy7M*1NS;NX*;LsAv07HG(5u@vML$2N@;Yv%s=SI`Re2e`y3!@|>gWsTa|cykjl?47 z;}h@?PP8f5H|4|7)Pu14U}ZJr{D{@!KY?D&{#o?u#C_1K)qWhky1**5t-%a`nJ?Bj zK8>&8(yFl6(W_}pYo_rH#A+HJGX*v>1-@nqY=Hh`uzZi@z++Y_HD<+JBUP+_{QMow z`8%UmBcFj@Et9V36<`)~{x&$DdIao_yn<|p`0e0MHzX(CoDIhRI#zMkU>SUiW$;h% zz;xLNTr!n^gFcU@RUS{_?1_Tsz{GeC91z^;2AVtFpnS2{;?v#|$19!I=+(40!>H7# zGnrApfmn^UC3@xjI{Hb0%7-~(-tAzV-(j3HgPl`Rj7xcZil%0=7-BV(U!hks_%(Vp z;`8X$ncqd569{~iFZT9;O#Y)~Ph3-t@uok<$e;eB~FeAtMe~!|IH*ny$V$jRH807{iSG z0nuRAhGN!Q26xFfap-fwOgxQfTTsvTe6c2R^SAI5RZl1MYNd2Rugsq`=B>@8yCJVG z-4^lb!2D>A*Z_66S7#WEBUJ5!(BBE>;Vz!}{!-8As_e74vEsgnUY+b~^osjD`hh_q zS5QdPV6e@wP+A3Lwa*%RJw6pZa4U7;8@M2rOXPw-75Lq8H5EO~a5~^9H5K0?R#VXn zy_$*)C{T^*E&N=OIE^ad6k;_MU*pj+ zV40Nz8--xuC&j{V65M54m?hWLEVbs@VguuoF&ZaT6^%u&?f|`Ual8QFDVZ(SG(J`D;C5=N2IAd-i}A@hgNvz?UqG)a`wG3f z$T{>og6Y_a>8KFwtbfM6Odn}E5(%a&Ii@R9@T~o$xyn=McLcB6cjB>kZ%VbxQcu+T(9WXmN85>Z5Upe| zE#-2?-Wh;Do>Du>M^`1<rE?hVJAIc^ zgZLg}%p7=RF~>ZeEjBo=J`hK!s;1)Xs;bH8)nmzY^lBx&gP*JOzKwp0eoRu?9}%?( z)ymnf z6yMX_!;L-;re-N1rzsOMZ;Si^N|`t;4aZ;Lp&j zLRX_#w^@mPSWw#t)Yd8hZ4KVNL9`E1tKi7iI5JhBkQxg6lBtDr4v*T0(Y{1Ggf?Hl z@vRoj_oy!#jAy+W&ssB{HD)}k(B}>m9$;Ax53V^9*E|^PbPwSUvoUxDuosU?*W$%4 zGbdkaPQKWjd=dH%dRkTK{SYM%E|mnAY8kxsIuC;_k7M3Muee&HSGQ@4{*!>@0Z29l zL)eG&#e%c z&p2o#85aW%w<6RlwWm)#LmX^s0~}Xsv?* zevIr_snnz6W$aJCK|6+a5$zz_*Jz`H!HmfnD<3bjCCaQ2{G=kHazU9D%#|vk?--Oh z0A;odZqXgLSQ11l5Ty&2^5SLuqAuL@q={Dg|tquvkb)sp%iy&C3s=+!N6qc5!2u{wWIL`#EVuEd#Y1tr|W z&g@%tKUW7{$1v5+|3?2zaD)Hh25keUg&16pz-clf<&+z}8o)DV=((`)_r#(9!09Rl zr>la~B?wM1#GD|pIe}+RkP!Xqpx&QRfvWdM^s3%_=+))!qE`dHgT6>mZ!tV{+=^d3 zS=QK_@i#kid;a!4k*W_jn~$4$cyhR=*L&oKzDVS{e~ktBVJ;jLL9e!o5!_fIMQ~$0 z9Y=2JAw;hDJHse`s^%_=pQ?xOqv$cR$W`38gEcV?4;t+P$weqJXAn(6R5N(fzYZ>{ z3af|yqJEL5?lhOsIs|8n;cPDj6Zt(Ra&LShulZN^{z4xOb zR}+~8y^@WhR|80tE!JM$ht<9%ioqzhMCjGiRTA{eg0ru}*>eTavxp7^@0_&6+0@Ja z`{>omZ-ri6?Kkx5Y6H=$s~tsqGa&f{*=K@iDx%keIc|n)*9y4mB2u@nkD1>WpZTO& zW0m7G|172_4-QBO5LLoF+(6CzPJiZiqc}vn{F(n4KU6cH0KJ;|1h}!9`2@JJn)y9? z(2?!_%zOB$nt2aDRWpACJ;oB*f#n)t{|;;~C}kK*IT-wo&N)O1;Us!h#H47fgL=P2 zk*C1PFitNS`rJ6_E&m#+{A+kg(6WREv=4x_2xpgD+^CwM3OIXv|*4c^A-fOD(){0qIB&lq}D!XM~W2@}y)1jVmJ z@l}JBQ7vc8`ziR@!+Zl$7f;cyU$1su+BS{M=vq8^y;fb?w@X?)DH3>T94(%_b-VVl zF6#WnleO#Drc>pvB~m3Vfj=)8m9PXh)WZ{&NE@Wa>eLuJwKb7CYH}hRgFh! z^bVDdr}pU7ZvV)A!I6(ARwqcC*gEnJovNWyc!`)eeu9fSeb!HZ6QpnG^kw@5w{_~4 zow}z}-}yIAhrdnX7g;@tx_Z7O*40<*)F*Zde?b>V;d6WbtHw*FQjuhOj3txB&sSBa z%lYYALArrX*H!8Gk!^IUwSVMLO#c?NFN0g`)<53i|M&=gbT0VOb^W7j_Q|~DdNj%X z(Ik&wqr6U+Q|WlBs!mn0Q?+!ehMnrJQ{C*;Fr6BzQW$G+i9I^K!#;AqPVMuLJQ5sv zU8k@4=?GSTNi_8*%wWrPbu2a|i6O~RC zzj1|Bx|URaEqG>8@7k(onPb5rr}ZHx{X@>;M`|aRKXv>J#Z#*@6ijWE_Nq=*Q7Qb% za&Y7(onB`jxkaZo+o>Zuwck!*WnyFGS4la=|ts22gX?6M){PL}TzbvBDh5dA~Al*c#U-Q!~(#Ma^ zkWroFv5eL@3+mJ>cB;Nk)w5GQb*hJ*+Nx6nCjl}eCB z-?(6w_>GI}bYVYT60a%C2S4hmf7DU^D1P+8r`1WeKW(M{)v15%RI2RisFc~Qqb};y zaXWQIr!J`!Ubx_QqW!vW==3%F$RBm;rk%>0PhH~qeAXpC)Tx;&g(u7@lSOqh z7A=F{n2okOfq%_S4=oxyq0inP-G68A;U~LLa+seSK*@1_awH{J_{mQxS@ER4P9kEcDkpv^|xh;|z7C$yBSu|Yzsh}IHqAle6L>(Gv) zeUFxO4Yp)xWzm|U^+TJ6wi@j)+HJIipW&W}Rub(sv|ebF(3Yd^N4tTRU@huLD~i?t ztsB~Sv?XY}(XOEVg_da@>PM@C)(LG4+CsGLXcy5QqGec*`q65lbwC?|HV6I<(_x-=ihnhWgRUqBTS7hc*puHQHgc+h_^#LLxg_ zNwn9{dZA51TaLCL?FL$c9jG6zC|U!wZfN7tmZ0rMyMp!?S|+@pDTr1FtrOZ9w1sHf z(JrDrM9Z)X^`q59>wq=_Z64YdwDV{W(9+@+(TiwR(b}R7L7R=X5$!bEPiQIeIw%iX zMYNV^1JOP}TZeWW?R&JOdr?1HS+r(o{m`bNtwuYHb{j3>KGcs^674m#UTBlhmZR-Q zyMdNqKk7#-iq-(F8`^lZC1|_RuAu#emgxZMN2`O@32hA8LbUB@7ttP~Wx(%W=R>QB z)&Xq<+B~!^Xy?%$prt*8`q8SQwM83(HXCgt+G(_(&{7^o{b&`@TA~d^`v7en+Hth+ z(UKlP{b*&;nxXYWn})U;?J(MHw1h`dKUzt&*U);QO+s6awjb>VT7qM!AFU`_1GH{v zPoyPXDq_2u9H1{{6ce}3+%pP#X_ND$wJM+Ya+&&S!(>F3rr zV`+*f?bN52dWwyoFw1gv!pQRfPUscUsi*B!eVr<1r@HD?LpwE2r@Gsz#X2>?PVLgE zrFQDFPVKQ%f9lj#JC$*T8tUJ6s(?;qUSW;CwoVnYQyq1xuALgKQ=RS90-YLbr?%-*xJeol3t_Pm`U>t5c7!w1!$kr}EpW_BvI|P7T+on4OxdQzPxvW}TXE zr_SlrRy%cHr@pdNX;!JB{%WUQ(5ZB*tf5xXsh8|j8=b0Vrv~d(J3BQ?r-s_84LUW) zPMy-JO?K)>ojPNuQmj@({n<|C)~Qsht)W)Xspsre3!SQDrv~U$D?2qqrv}-nwK_G^ zP94*!^>*s6PMxq*N!F;L-m_EB=v1;b)=slGbZ+)ho^ss46ql}=5! zQ-^eFjh(usQ%CGn^fNWoJ9a9YP9^%x8fpoh%3-G(>r^Q_)l;XM*r|y+)!R-j)2YdJ zYM)N6uv6D{>VTd4SEp{;sVr;N=p$>bp%&4pr|ndIohoLhy6RLzJ2g(Hy4$J6IyJ#g z?b4~GcIvWD?XgpT>eN*`m2sUK>fd&%fKFvzXN|tLP8G6K9d)X%of@rEo$b^Dof>PW zw&~O&J9R;)cG#)kb?TCxO21wW^^u**t5c7!w}x6nr}EpW_BvI|P7T+on4OxdQzPxv zW}TXEr_SlrRy%cHr@pdNX+Bp&{nbvrpi}8Sw}x6pr(UvCZFH)dof@oD?d;Snof>MV zHt5tGJ9SE@Hrc5kb?S_rO0hu=^=CVkTc=WOu!dSer=GJ@Ep)1qof@E1t?bkcof>4P z*6P$uJ9SK_*4wGOI(5QMCE2Kkde2Thqf^N?T0r^Q_)l;XM*r|y+)!R-j z)2YdJYM)N6uv6D{>VTd4SEp{;sVrZp(MP_phFV0Yp0-oZ(%>?bJA(>TahN z>(m50wM(a#+NsMrwZ~5VsZ&?&RL0F}sDIn30y>p>vo-qKI#tL{b=0Z4c51Xvb+%Ir zbZV@f+NM*B?9>IF+F_@D*QrZ(D*YBU)JJwIuTDL_#Tsf2oyu>g+Ury;J2hOVVs>h- zPK~rvn{{fwojRveTkX_+o%+g7rP->6`m3FKL8sDfwT4MVHt5tGJ9SE@Hrc5kb?S_rO7W!{>d$s6w@#({(i&<7oqEnrwa}?bc4~l5wX#z) zbZU^DTB}nt?bI=yT5qTB>eLB4m1LV5>ODL4j7}xnW(~EBPUW&wO?9fAo$9Mo&F$1w zo$7C=R_WAqJ9S8>*4U|AI(5WOMYpS=-mz2JbSlwyYp5l3DuseL-N!cJY+sRMTEU!A&Xr?Tu&qmS&chFV0Yp0-oZ(%>?bJA( z>TahN>(m50wM(a#+NsMrwZ~5VsZ&?&RK}fZsDIn30y>p>r#1T8I#tL{b=0Z4c51Xv zb+%IrbZV@f+NM*B?9>IF+F_@D*QrZ(D*Y}s)JJwIuTDL_%NlA8oyu>g+Ury;J2hOV zVs>h-PK~rvn{{fwojRveTkX_+o%+g7rP-~9`m3FKL8sE~wuV|or(UvCZFH)dof@oD z?d;Snof>MVHt5tGJ9SE@Hrc5kb?S_rO0h=`^=CVkTc=X(v4&bfr=GJ@Ep)1qof@E1 zt?bkcof>4P*6P$uJ9SK_*4wGOI(5QMCE2Tnde2Thqf^QDT0r^Q_)l;XM z*r|y+)!R-j)2YdJYM)N6uv6D{>VTd4SEp{;sVw`|=p*~Bp%&4pr|ndIohoLhy6RLz zJ2g(Hy4$J6IyJ#g?b4~GcIvWD?XgpT>eN*`mGOWY>fd&%fKFvTV2!@EP8G6K9d)X% zof@rEo$b^Dof>PWw&~O&J9R;)cG#)kb?TCxN`Fud^^u**t5c63w1!$kr}EpW_BvI| zP7T+on4OxdQzPxvW}TXEr_SlrRy%cHr@pdNX%4BO{%WUQ(5ZBXtf5xXsh8|j8=b0V zrv~d(J3BQ?r-s_84LUW)PMy-JO?K)>ojPNuQXE!8{n<|C)~Qs7t)W)Xspsre3!SQD zrv~U$D?2qqrv}-nwK_G^P94*!^>*s6PMxq*Nsg$Y-m_EB=v1;J)= zslGbZ+)ho^ss46ql}=5!Q-^eFjh(usQ%CGn^r#x@9XpjxrxG2thFU_Wa@eWHI#tR} z_0*{*c50$d^|n*XbZWAl+NV=1?9_FgI$)>%)v23yD$6l7`p7YBs6}+@X**S4r;6FB zt~%AwPL0#4?sjUiPED{=yL4))ow}@3d+gMoI(5}fWjwBi`nR1bpi`NTTcfY7Q-$nQ zN1du`r$*~kXFIh(r^ec;Z928cPF>Kc9d_z>ow{VF(w|U6ePpNd>eS;WtfAJ>sr+`T zy-wA#Q^R#CW~b)r)JQwES*PaPsdGBD)lS{lsjuu*nv-g%zuKu6bSm9RYp7Lp>LokX zMyIOTslhtc&Q8tJsiAgigHFw{Q>S!llb!ler_R`^6sOcsf3{P(bt=^Nz{r zLZ>R(sR26G%1+JDsX=yXtxnCfQ^#~_y`8$NQzz_HlGAFa_w3X&I+g6SHPkXXmCH^w z)v0oJs;^Epw^LJfs=u9DrBl=G)FGW(W2bKE)Db%sJ)?$t$4+I_sYGY2p_b689CoU) zPL;A#J$0&yotmgqz3tR8otkW?_UY6LJ9S;B4%n%Gb?T;_%5qkXK62I?Y7w1!+D_Hi zsbY4jt4=kvQ{!~1yPaCBQxojeE}dFxr!MQ%9y|4?PF=NA8PBPq{%xlU=v3x&*63^N zR3SUnQK#zKsnI&s*-kCcsj(_mJaMo8en09_I(6A4=~O;Rn;x;p2H>wBaY8HGP#&mK#FFMNU_zH{U2Eqvi$)>YpJ)ps>~MMmQICB+v$ z^GSXGpuRifE3!;|Kaa1P_=>!X-yev?lHm)V{-nNtRNr0j6XQr}(i6*5O^y@Kza_=>Di-}&&B249g=>boAkBERbI&tj3!V)^ma3ty4R`0a)4v9$QYhi~A! zKECkrE$Vx%`hEppz3~;9g1?EGJ(dn%ku&PM0lp%?>+f~3$hueoeD%RsWGa4VB75vH zd_~Tx?}qq_Jk;Oo|4&Evwv1&Mhhcnfr+}<^i8D~v%SvaE79>ghkHF$XP3a6o$%LXa zD2o5W#~AXVKkg1R$DMwe*XQnwyM}QT zK!05?^qTz&51ytrLK|@%6DS0mX}Sx|bNK@g@-wAP*MLb}0jp`c2Q6?qg$K`EBXZDI z>Yu0G_n|i&Wyy;oFoC5eOhMbJgU~@dfZpz57&kPl!M8Tn@a73cA_1Rp!aDe zTM-o=4!P;nZZJ0KfR;Hzqo@R!8Nx8kbs7~*Sb&vk*VlUsEehM?!1 zxyihOp>8m7avxkZom?AbmHnT3Vllb4z9(#4ZUKkmt6wO3TNQ} diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index cce8d5d..f39f264 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -1,9 +1,15 @@ +# encoding: utf-8 + require 'test/unit' $:.unshift "#{File.dirname(__FILE__)}/../lib" $:.unshift File.dirname(__FILE__) require 'active_support' +if RUBY_VERSION < '1.9' + $KCODE = 'UTF8' +end + def uses_gem(gem_name, test_name, version = '> 0') require 'rubygems' gem gem_name.to_s, version @@ -21,4 +27,4 @@ unless defined? uses_mocha end # Show backtraces for deprecated behavior for quicker cleanup. -ActiveSupport::Deprecation.debug = true +ActiveSupport::Deprecation.debug = true \ No newline at end of file diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index a87309b..31b8f1b 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -1,186 +1,528 @@ # encoding: utf-8 + require 'abstract_unit' -if RUBY_VERSION < '1.9' +module MultibyteTest + UNICODE_STRING = 'こにちわ' + ASCII_STRING = 'ohayo' + BYTE_STRING = "\270\236\010\210\245" + + def chars(str) + ActiveSupport::Multibyte::Chars.new(str) + end + + def inspect_codepoints(str) + str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ') + end + + def assert_equal_codepoints(expected, actual, message=nil) + assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message) + end +end + +class String + def __string_for_multibyte_testing; self; end + def __string_for_multibyte_testing!; self; end +end -$KCODE = 'UTF8' +class MultibyteCharsTest < Test::Unit::TestCase + include MultibyteTest -class CharsTest < Test::Unit::TestCase - def setup - @s = { - :utf8 => "Abcd Блå ffi блa 埋", - :ascii => "asci ias c iia s", - :bytes => "\270\236\010\210\245" - } + @chars = ActiveSupport::Multibyte::Chars.new UNICODE_STRING end - - def test_sanity - @s.each do |t, s| - assert s.respond_to?(:chars), "All string should have the chars method (#{t})" - assert s.respond_to?(:to_s), "All string should have the to_s method (#{t})" - assert_kind_of ActiveSupport::Multibyte::Chars, s.chars, "#chars should return an instance of Chars (#{t})" - end + + def test_wraps_the_original_string + assert_equal UNICODE_STRING, @chars.to_s + assert_equal UNICODE_STRING, @chars.wrapped_string end - - def test_comparability - @s.each do |t, s| - assert_equal s, s.chars.to_s, "Chars#to_s should return enclosed string unchanged" - end + + def test_should_allow_method_calls_to_string assert_nothing_raised do - assert_equal "a", "a", "Normal string comparisons should be unaffected" - assert_not_equal "a", "b", "Normal string comparisons should be unaffected" - assert_not_equal "a".chars, "b".chars, "Chars objects should be comparable" - assert_equal "a".chars, "A".downcase.chars, "Chars objects should be comparable to each other" - assert_equal "a".chars, "A".downcase, "Chars objects should be comparable to strings coming from elsewhere" + @chars.__string_for_multibyte_testing end - - assert !@s[:utf8].eql?(@s[:utf8].chars), "Strict comparison is not supported" - assert_equal @s[:utf8], @s[:utf8].chars, "Chars should be compared by their enclosed string" - - other_string = @s[:utf8].dup - assert_equal other_string, @s[:utf8].chars, "Chars should be compared by their enclosed string" - assert_equal other_string.chars, @s[:utf8].chars, "Chars should be compared by their enclosed string" - - strings = ['builder'.chars, 'armor'.chars, 'zebra'.chars] - strings.sort! - assert_equal ['armor', 'builder', 'zebra'], strings, "Chars should be sortable based on their enclosed string" - - # This leads to a StackLevelTooDeep exception if the comparison is not wired properly - assert_raise(NameError) do - Chars + assert_raises NoMethodError do + @chars.__unknown_method end end - - def test_utf8? - assert @s[:utf8].is_utf8?, "UTF-8 strings are UTF-8" - assert @s[:ascii].is_utf8?, "All ASCII strings are also valid UTF-8" - assert !@s[:bytes].is_utf8?, "This bytestring isn't UTF-8" - end - - # The test for the following methods are defined here because they can only be defined on the Chars class for - # various reasons - - def test_gsub - assert_equal 'éxa', 'éda'.chars.gsub(/d/, 'x') - with_kcode('none') do - assert_equal 'éxa', 'éda'.chars.gsub(/d/, 'x') - end + + def test_forwarded_method_calls_should_return_new_chars_instance + assert @chars.__string_for_multibyte_testing.kind_of?(ActiveSupport::Multibyte::Chars) + assert_not_equal @chars.object_id, @chars.__string_for_multibyte_testing.object_id end - - def test_split - word = "efficient" - chars = ["e", "ffi", "c", "i", "e", "n", "t"] - assert_equal chars, word.split(//) - assert_equal chars, word.chars.split(//) - assert_kind_of ActiveSupport::Multibyte::Chars, word.chars.split(//).first, "Split should return Chars instances" - end - - def test_regexp - with_kcode('none') do - assert_equal 12, (@s[:utf8].chars =~ /ffi/), - "Regex matching should be bypassed to String" + + def test_forwarded_bang_method_calls_should_return_the_original_chars_instance + assert @chars.__string_for_multibyte_testing!.kind_of?(ActiveSupport::Multibyte::Chars) + assert_equal @chars.object_id, @chars.__string_for_multibyte_testing!.object_id + end + + def test_methods_are_forwarded_to_wrapped_string_for_byte_strings + assert_equal BYTE_STRING.class, BYTE_STRING.mb_chars.class + end + + def test_should_concatenate + assert_equal 'ab', 'a'.mb_chars + 'b' + assert_equal 'ab', 'a' + 'b'.mb_chars + assert_equal 'ab', 'a'.mb_chars + 'b'.mb_chars + + assert_equal 'ab', 'a'.mb_chars << 'b' + assert_equal 'ab', 'a' << 'b'.mb_chars + assert_equal 'ab', 'a'.mb_chars << 'b'.mb_chars + end + + if RUBY_VERSION < '1.9' + def test_concatenation_should_return_a_proxy_class_instance + assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars + 'b').class + assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars << 'b').class end - with_kcode('UTF8') do - assert_equal 9, (@s[:utf8].chars =~ /ffi/), - "Regex matching should be unicode aware" - assert_nil((''.chars =~ /\d+/), - "Non-matching regular expressions should return nil") + + def test_ascii_strings_are_treated_at_utf8_strings + assert_equal ActiveSupport::Multibyte.proxy_class, ASCII_STRING.mb_chars.class + end + + def test_concatenate_should_return_proxy_instance + assert(('a'.mb_chars + 'b').kind_of?(ActiveSupport::Multibyte::Chars)) + assert(('a'.mb_chars + 'b'.mb_chars).kind_of?(ActiveSupport::Multibyte::Chars)) + assert(('a'.mb_chars << 'b').kind_of?(ActiveSupport::Multibyte::Chars)) + assert(('a'.mb_chars << 'b'.mb_chars).kind_of?(ActiveSupport::Multibyte::Chars)) end end +end - def test_pragma - if RUBY_VERSION < '1.9' - with_kcode('UTF8') do - assert " ".chars.send(:utf8_pragma?), "UTF8 pragma should be on because KCODE is UTF8" - end - with_kcode('none') do - assert !" ".chars.send(:utf8_pragma?), "UTF8 pragma should be off because KCODE is not UTF8" +class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase + include MultibyteTest + + def setup + @chars = UNICODE_STRING.dup.mb_chars + + # NEWLINE, SPACE, EM SPACE + @whitespace = "\n#{[32, 8195].pack('U*')}" + @whitespace.force_encoding(Encoding::UTF_8) if @whitespace.respond_to?(:force_encoding) + @byte_order_mark = [65279].pack('U') + end + + if RUBY_VERSION < '1.9' + def test_split_should_return_an_array_of_chars_instances + @chars.split(//).each do |character| + assert character.kind_of?(ActiveSupport::Multibyte::Chars) end - else - assert !" ".chars.send(:utf8_pragma?), "UTF8 pragma should be off in Ruby 1.9" end - end - def test_handler_setting - handler = ''.chars.handler - - ActiveSupport::Multibyte::Chars.handler = :first - assert_equal :first, ''.chars.handler - ActiveSupport::Multibyte::Chars.handler = :second - assert_equal :second, ''.chars.handler - assert_raise(NoMethodError) do - ''.chars.handler.split + def test_indexed_insert_accepts_fixnums + @chars[2] = 32 + assert_equal 'こに わ', @chars end - - ActiveSupport::Multibyte::Chars.handler = handler - end - - def test_method_chaining - assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.downcase - assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.strip, "Strip should return a Chars object" - assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.downcase.strip, "The Chars object should be " + - "forwarded down the call path for chaining" - assert_equal 'foo', " FOO ".chars.normalize.downcase.strip, "The Chars that results from the " + - " operations should be comparable to the string value of the result" - end - - def test_passthrough_on_kcode - # The easiest way to check if the passthrough is in place is through #size - with_kcode('none') do - assert_equal 26, @s[:utf8].chars.size + + def test_overridden_bang_methods_return_self + [:rstrip!, :lstrip!, :strip!, :reverse!, :upcase!, :downcase!, :capitalize!].each do |method| + assert_equal @chars.object_id, @chars.send(method).object_id + end + assert_equal @chars.object_id, @chars.slice!(1).object_id end - with_kcode('UTF8') do - assert_equal 17, @s[:utf8].chars.size + + def test_overridden_bang_methods_change_wrapped_string + [:rstrip!, :lstrip!, :strip!, :reverse!, :upcase!, :downcase!].each do |method| + original = ' Café ' + proxy = chars(original.dup) + proxy.send(method) + assert_not_equal original, proxy.to_s + end + proxy = chars('Café') + proxy.slice!(3) + assert_equal 'é', proxy.to_s + + proxy = chars('òu') + proxy.capitalize! + assert_equal 'Òu', proxy.to_s end end - - def test_destructiveness - # Note that we're testing the destructiveness here and not the correct behaviour of the methods - str = 'ac' - str.chars.insert(1, 'b') - assert_equal 'abc', str, 'Insert should be destructive for a string' - - str = 'ac' - str.chars.reverse! - assert_equal 'ca', str, 'reverse! should be destructive for a string' - end - - def test_resilience - assert_nothing_raised do - assert_equal 5, @s[:bytes].chars.size, "The sequence contains five interpretable bytes" - end - reversed = [0xb8, 0x17e, 0x8, 0x2c6, 0xa5].reverse.pack('U*') - assert_nothing_raised do - assert_equal reversed, @s[:bytes].chars.reverse.to_s, "Reversing the string should only yield interpretable bytes" + + if RUBY_VERSION >= '1.9' + def test_unicode_string_should_have_utf8_encoding + assert_equal Encoding::UTF_8, UNICODE_STRING.encoding end - assert_nothing_raised do - @s[:bytes].chars.reverse! - assert_equal reversed, @s[:bytes].to_s, "Reversing the string should only yield interpretable bytes" + end + + def test_should_be_equal_to_the_wrapped_string + assert_equal UNICODE_STRING, @chars + assert_equal @chars, UNICODE_STRING + end + + def test_should_not_be_equal_to_an_other_string + assert_not_equal @chars, 'other' + assert_not_equal 'other', @chars + end + + def test_should_return_character_offset_for_regexp_matches + assert_nil(@chars =~ /wrong/u) + assert_equal 0, (@chars =~ /こ/u) + assert_equal 1, (@chars =~ /に/u) + assert_equal 3, (@chars =~ /わ/u) + end + + def test_should_use_character_offsets_for_insert_offsets + assert_equal '', ''.mb_chars.insert(0, '') + assert_equal 'こわにちわ', @chars.insert(1, 'わ') + assert_equal 'こわわわにちわ', @chars.insert(2, 'わわ') + assert_equal 'わこわわわにちわ', @chars.insert(0, 'わ') + assert_equal 'わこわわわにちわ', @chars.wrapped_string if RUBY_VERSION < '1.9' + end + + def test_insert_should_be_destructive + @chars.insert(1, 'わ') + assert_equal 'こわにちわ', @chars + end + + def test_insert_throws_index_error + assert_raises(IndexError) { @chars.insert(12, 'わ') } + end + + def test_should_know_if_one_includes_the_other + assert @chars.include?('') + assert @chars.include?('ち') + assert @chars.include?('わ') + assert !@chars.include?('こちわ') + assert !@chars.include?('a') + end + + def test_include_raises_type_error_when_nil_is_passed + assert_raises(TypeError) do + @chars.include?(nil) end end - - def test_duck_typing - assert_equal true, 'test'.chars.respond_to?(:strip) - assert_equal true, 'test'.chars.respond_to?(:normalize) - assert_equal true, 'test'.chars.respond_to?(:normalize!) - assert_equal false, 'test'.chars.respond_to?(:a_method_that_doesnt_exist) + + def test_index_should_return_character_offset + assert_nil @chars.index('u') + assert_equal 0, @chars.index('こに') + assert_equal 2, @chars.index('ち') + assert_equal 3, @chars.index('わ') + end + + def test_indexed_insert_should_take_character_offsets + @chars[2] = 'a' + assert_equal 'こにaわ', @chars + @chars[2] = 'ηη' + assert_equal 'こにηηわ', @chars + @chars[3, 2] = 'λλλ' + assert_equal 'こにηλλλ', @chars + @chars[1, 0] = "λ" + assert_equal 'こλにηλλλ', @chars + @chars[4..6] = "ηη" + assert_equal 'こλにηηη', @chars + @chars[/ηη/] = "λλλ" + assert_equal 'こλにλλλη', @chars + @chars[/(λλ)(.)/, 2] = "α" + assert_equal 'こλにλλαη', @chars + @chars["α"] = "¢" + assert_equal 'こλにλλ¢η', @chars + @chars["λλ"] = "ααα" + assert_equal 'こλにααα¢η', @chars + end + + def test_indexed_insert_should_raise_on_index_overflow + before = @chars.to_s + assert_raises(IndexError) { @chars[10] = 'a' } + assert_raises(IndexError) { @chars[10, 4] = 'a' } + assert_raises(IndexError) { @chars[/ii/] = 'a' } + assert_raises(IndexError) { @chars[/()/, 10] = 'a' } + assert_equal before, @chars + end + + def test_indexed_insert_should_raise_on_range_overflow + before = @chars.to_s + assert_raises(RangeError) { @chars[10..12] = 'a' } + assert_equal before, @chars end - + + def test_rjust_should_raise_argument_errors_on_bad_arguments + assert_raises(ArgumentError) { @chars.rjust(10, '') } + assert_raises(ArgumentError) { @chars.rjust } + end + + def test_rjust_should_count_characters_instead_of_bytes + assert_equal UNICODE_STRING, @chars.rjust(-3) + assert_equal UNICODE_STRING, @chars.rjust(0) + assert_equal UNICODE_STRING, @chars.rjust(4) + assert_equal " #{UNICODE_STRING}", @chars.rjust(5) + assert_equal " #{UNICODE_STRING}", @chars.rjust(7) + assert_equal "---#{UNICODE_STRING}", @chars.rjust(7, '-') + assert_equal "ααα#{UNICODE_STRING}", @chars.rjust(7, 'α') + assert_equal "aba#{UNICODE_STRING}", @chars.rjust(7, 'ab') + assert_equal "αηα#{UNICODE_STRING}", @chars.rjust(7, 'αη') + assert_equal "αηαη#{UNICODE_STRING}", @chars.rjust(8, 'αη') + end + + def test_ljust_should_raise_argument_errors_on_bad_arguments + assert_raises(ArgumentError) { @chars.ljust(10, '') } + assert_raises(ArgumentError) { @chars.ljust } + end + + def test_ljust_should_count_characters_instead_of_bytes + assert_equal UNICODE_STRING, @chars.ljust(-3) + assert_equal UNICODE_STRING, @chars.ljust(0) + assert_equal UNICODE_STRING, @chars.ljust(4) + assert_equal "#{UNICODE_STRING} ", @chars.ljust(5) + assert_equal "#{UNICODE_STRING} ", @chars.ljust(7) + assert_equal "#{UNICODE_STRING}---", @chars.ljust(7, '-') + assert_equal "#{UNICODE_STRING}ααα", @chars.ljust(7, 'α') + assert_equal "#{UNICODE_STRING}aba", @chars.ljust(7, 'ab') + assert_equal "#{UNICODE_STRING}αηα", @chars.ljust(7, 'αη') + assert_equal "#{UNICODE_STRING}αηαη", @chars.ljust(8, 'αη') + end + + def test_center_should_raise_argument_errors_on_bad_arguments + assert_raises(ArgumentError) { @chars.center(10, '') } + assert_raises(ArgumentError) { @chars.center } + end + + def test_center_should_count_charactes_instead_of_bytes + assert_equal UNICODE_STRING, @chars.center(-3) + assert_equal UNICODE_STRING, @chars.center(0) + assert_equal UNICODE_STRING, @chars.center(4) + assert_equal "#{UNICODE_STRING} ", @chars.center(5) + assert_equal " #{UNICODE_STRING} ", @chars.center(6) + assert_equal " #{UNICODE_STRING} ", @chars.center(7) + assert_equal "--#{UNICODE_STRING}--", @chars.center(8, '-') + assert_equal "--#{UNICODE_STRING}---", @chars.center(9, '-') + assert_equal "αα#{UNICODE_STRING}αα", @chars.center(8, 'α') + assert_equal "αα#{UNICODE_STRING}ααα", @chars.center(9, 'α') + assert_equal "a#{UNICODE_STRING}ab", @chars.center(7, 'ab') + assert_equal "ab#{UNICODE_STRING}ab", @chars.center(8, 'ab') + assert_equal "abab#{UNICODE_STRING}abab", @chars.center(12, 'ab') + assert_equal "α#{UNICODE_STRING}αη", @chars.center(7, 'αη') + assert_equal "αη#{UNICODE_STRING}αη", @chars.center(8, 'αη') + end + + def test_lstrip_strips_whitespace_from_the_left_of_the_string + assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.lstrip + assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING).mb_chars.lstrip + assert_equal UNICODE_STRING + @whitespace, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.lstrip + end + + def test_rstrip_strips_whitespace_from_the_right_of_the_string + assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.rstrip + assert_equal UNICODE_STRING, (UNICODE_STRING + @whitespace).mb_chars.rstrip + assert_equal @whitespace + UNICODE_STRING, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.rstrip + end + + def test_strip_strips_whitespace + assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.strip + assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING).mb_chars.strip + assert_equal UNICODE_STRING, (UNICODE_STRING + @whitespace).mb_chars.strip + assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.strip + end + + def test_stripping_whitespace_leaves_whitespace_within_the_string_intact + string_with_whitespace = UNICODE_STRING + @whitespace + UNICODE_STRING + assert_equal string_with_whitespace, string_with_whitespace.mb_chars.strip + assert_equal string_with_whitespace, string_with_whitespace.mb_chars.lstrip + assert_equal string_with_whitespace, string_with_whitespace.mb_chars.rstrip + end + + def test_size_returns_characters_instead_of_bytes + assert_equal 0, ''.mb_chars.size + assert_equal 4, @chars.size + assert_equal 4, @chars.length + assert_equal 5, ASCII_STRING.mb_chars.size + end + + def test_reverse_reverses_characters + assert_equal '', ''.mb_chars.reverse + assert_equal 'わちにこ', @chars.reverse + end + + def test_slice_should_take_character_offsets + assert_equal nil, ''.mb_chars.slice(0) + assert_equal 'こ', @chars.slice(0) + assert_equal 'わ', @chars.slice(3) + assert_equal nil, ''.mb_chars.slice(-1..1) + assert_equal '', ''.mb_chars.slice(0..10) + assert_equal 'にちわ', @chars.slice(1..3) + assert_equal 'にちわ', @chars.slice(1, 3) + assert_equal 'こ', @chars.slice(0, 1) + assert_equal 'ちわ', @chars.slice(2..10) + assert_equal '', @chars.slice(4..10) + assert_equal 'に', @chars.slice(/に/u) + assert_equal 'にち', @chars.slice(/に\w/u) + assert_equal nil, @chars.slice(/unknown/u) + assert_equal 'にち', @chars.slice(/(にち)/u, 1) + assert_equal nil, @chars.slice(/(にち)/u, 2) + assert_equal nil, @chars.slice(7..6) + end + + def test_slice_should_throw_exceptions_on_invalid_arguments + assert_raise(TypeError) { @chars.slice(2..3, 1) } + assert_raise(TypeError) { @chars.slice(1, 2..3) } + assert_raise(ArgumentError) { @chars.slice(1, 1, 1) } + end + + def test_upcase_should_upcase_ascii_characters + assert_equal '', ''.mb_chars.upcase + assert_equal 'ABC', 'aBc'.mb_chars.upcase + end + + def test_downcase_should_downcase_ascii_characters + assert_equal '', ''.mb_chars.downcase + assert_equal 'abc', 'aBc'.mb_chars.downcase + end + + def test_capitalize_should_work_on_ascii_characters + assert_equal '', ''.mb_chars.capitalize + assert_equal 'Abc', 'abc'.mb_chars.capitalize + end + + def test_respond_to_knows_which_methods_the_proxy_responds_to + assert ''.mb_chars.respond_to?(:slice) # Defined on Chars + assert ''.mb_chars.respond_to?(:capitalize!) # Defined on Chars + assert ''.mb_chars.respond_to?(:gsub) # Defined on String + assert !''.mb_chars.respond_to?(:undefined_method) # Not defined + end + def test_acts_like_string - assert 'Bambi'.chars.acts_like_string? + assert 'Bambi'.mb_chars.acts_like_string? end +end - protected +# The default Multibyte Chars proxy has more features than the normal string implementation. Tests +# for the implementation of these features should run on all Ruby versions and shouldn't be tested +# through the proxy methods. +class MultibyteCharsExtrasTest < Test::Unit::TestCase + include MultibyteTest - def with_kcode(kcode) - old_kcode, $KCODE = $KCODE, kcode - begin - yield - ensure - $KCODE = old_kcode + if RUBY_VERSION >= '1.9' + def test_tidy_bytes_is_broken_on_1_9_0 + assert_raises(ArgumentError) do + assert_equal_codepoints [0xfffd].pack('U'), chars("\xef\xbf\xbd").tidy_bytes + end end end -end + def test_upcase_should_be_unicode_aware + assert_equal "АБВГД\0F", chars("аБвгд\0f").upcase + assert_equal 'こにちわ', chars('こにちわ').upcase + end + + def test_downcase_should_be_unicode_aware + assert_equal "абвгд\0f", chars("аБвгд\0f").downcase + assert_equal 'こにちわ', chars('こにちわ').downcase + end + + def test_capitalize_should_be_unicode_aware + { 'аБвг аБвг' => 'Абвг абвг', + 'аБвг АБВГ' => 'Абвг абвг', + 'АБВГ АБВГ' => 'Абвг абвг', + '' => '' }.each do |f,t| + assert_equal t, chars(f).capitalize + end + end + + def test_composition_exclusion_is_set_up_properly + # Normalization of DEVANAGARI LETTER QA breaks when composition exclusion isn't used correctly + qa = [0x915, 0x93c].pack('U*') + assert_equal qa, chars(qa).normalize(:c) + end + + # Test for the Public Review Issue #29, bad explanation of composition might lead to a + # bad implementation: http://www.unicode.org/review/pr-29.html + def test_normalization_C_pri_29 + [ + [0x0B47, 0x0300, 0x0B3E], + [0x1100, 0x0300, 0x1161] + ].map { |c| c.pack('U*') }.each do |c| + assert_equal_codepoints c, chars(c).normalize(:c) + end + end + + def test_normalization_shouldnt_strip_null_bytes + null_byte_str = "Test\0test" + + assert_equal null_byte_str, chars(null_byte_str).normalize(:kc) + assert_equal null_byte_str, chars(null_byte_str).normalize(:c) + assert_equal null_byte_str, chars(null_byte_str).normalize(:d) + assert_equal null_byte_str, chars(null_byte_str).normalize(:kd) + assert_equal null_byte_str, chars(null_byte_str).decompose + assert_equal null_byte_str, chars(null_byte_str).compose + end + + def test_simple_normalization + comp_str = [ + 44, # LATIN CAPITAL LETTER D + 307, # COMBINING DOT ABOVE + 328, # COMBINING OGONEK + 323 # COMBINING DOT BELOW + ].pack("U*") + + assert_equal_codepoints '', chars('').normalize + assert_equal_codepoints [44,105,106,328,323].pack("U*"), chars(comp_str).normalize(:kc).to_s + assert_equal_codepoints [44,307,328,323].pack("U*"), chars(comp_str).normalize(:c).to_s + assert_equal_codepoints [44,307,110,780,78,769].pack("U*"), chars(comp_str).normalize(:d).to_s + assert_equal_codepoints [44,105,106,110,780,78,769].pack("U*"), chars(comp_str).normalize(:kd).to_s + end + + def test_should_compute_grapheme_length + [ + ['', 0], + ['abc', 3], + ['こにちわ', 4], + [[0x0924, 0x094D, 0x0930].pack('U*'), 2], + [%w(cr lf), 1], + [%w(l l), 1], + [%w(l v), 1], + [%w(l lv), 1], + [%w(l lvt), 1], + [%w(lv v), 1], + [%w(lv t), 1], + [%w(v v), 1], + [%w(v t), 1], + [%w(lvt t), 1], + [%w(t t), 1], + [%w(n extend), 1], + [%w(n n), 2], + [%w(n cr lf n), 3], + [%w(n l v t), 2] + ].each do |input, expected_length| + if input.kind_of?(Array) + str = string_from_classes(input) + else + str = input + end + assert_equal expected_length, chars(str).g_length + end + end + + def test_tidy_bytes_should_tidy_bytes + byte_string = "\270\236\010\210\245" + tidy_string = [0xb8, 0x17e, 0x8, 0x2c6, 0xa5].pack('U*') + ascii_padding = 'aa' + utf8_padding = 'éé' + + assert_equal_codepoints tidy_string, chars(byte_string).tidy_bytes + + assert_equal_codepoints ascii_padding.dup.insert(1, tidy_string), + chars(ascii_padding.dup.insert(1, byte_string)).tidy_bytes + assert_equal_codepoints utf8_padding.dup.insert(2, tidy_string), + chars(utf8_padding.dup.insert(2, byte_string)).tidy_bytes + assert_nothing_raised { chars(byte_string).tidy_bytes.to_s.unpack('U*') } + + assert_equal_codepoints "\xC3\xA7", chars("\xE7").tidy_bytes # iso_8859_1: small c cedilla + assert_equal_codepoints "\xE2\x80\x9C", chars("\x93").tidy_bytes # win_1252: left smart quote + assert_equal_codepoints "\xE2\x82\xAC", chars("\x80").tidy_bytes # win_1252: euro + assert_equal_codepoints "\x00", chars("\x00").tidy_bytes # null char + assert_equal_codepoints [0xfffd].pack('U'), chars("\xef\xbf\xbd").tidy_bytes # invalid char + rescue ArgumentError => e + raise e if RUBY_VERSION < '1.9' + end + + private + + def string_from_classes(classes) + # Characters from the character classes as described in UAX #29 + character_from_class = { + :l => 0x1100, :v => 0x1160, :t => 0x11A8, :lv => 0xAC00, :lvt => 0xAC01, :cr => 0x000D, :lf => 0x000A, + :extend => 0x094D, :n => 0x64 + } + classes.collect do |k| + character_from_class[k.intern] + end.pack('U*') + end end diff --git a/activesupport/test/multibyte_conformance.rb b/activesupport/test/multibyte_conformance.rb index 05fb9ef..fe6cd70 100644 --- a/activesupport/test/multibyte_conformance.rb +++ b/activesupport/test/multibyte_conformance.rb @@ -1,13 +1,7 @@ require 'abstract_unit' +require 'fileutils' require 'open-uri' - -if RUBY_VERSION < '1.9' - -$KCODE = 'UTF8' - -UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd" -UNIDATA_FILE = '/NormalizationTest.txt' -CACHE_DIR = File.dirname(__FILE__) + '/cache' +require 'tmpdir' class Downloader def self.download(from, to) @@ -27,17 +21,19 @@ class Downloader end end -class String - # Unicode Inspect returns the codepoints of the string in hex - def ui - "#{self} " + ("[%s]" % unpack("U*").map{|cp| cp.to_s(16) }.join(' ')) - end unless ''.respond_to?(:ui) -end - -Dir.mkdir(CACHE_DIR) unless File.exist?(CACHE_DIR) -Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE) - -module ConformanceTest +class MultibyteConformanceTest < Test::Unit::TestCase + include MultibyteTest + + UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd" + UNIDATA_FILE = '/NormalizationTest.txt' + CACHE_DIR = File.join(Dir.tmpdir, 'cache') + + def setup + FileUtils.mkdir_p(CACHE_DIR) + Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE) + @proxy = ActiveSupport::Multibyte::Chars + end + def test_normalizations_C each_line_of_norm_tests do |*cols| col1, col2, col3, col4, col5, comment = *cols @@ -47,13 +43,13 @@ module ConformanceTest # # NFC # c2 == NFC(c1) == NFC(c2) == NFC(c3) - assert_equal col2.ui, @handler.normalize(col1, :c).ui, "Form C - Col 2 has to be NFC(1) - #{comment}" - assert_equal col2.ui, @handler.normalize(col2, :c).ui, "Form C - Col 2 has to be NFC(2) - #{comment}" - assert_equal col2.ui, @handler.normalize(col3, :c).ui, "Form C - Col 2 has to be NFC(3) - #{comment}" + assert_equal_codepoints col2, @proxy.new(col1).normalize(:c), "Form C - Col 2 has to be NFC(1) - #{comment}" + assert_equal_codepoints col2, @proxy.new(col2).normalize(:c), "Form C - Col 2 has to be NFC(2) - #{comment}" + assert_equal_codepoints col2, @proxy.new(col3).normalize(:c), "Form C - Col 2 has to be NFC(3) - #{comment}" # # c4 == NFC(c4) == NFC(c5) - assert_equal col4.ui, @handler.normalize(col4, :c).ui, "Form C - Col 4 has to be C(4) - #{comment}" - assert_equal col4.ui, @handler.normalize(col5, :c).ui, "Form C - Col 4 has to be C(5) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col4).normalize(:c), "Form C - Col 4 has to be C(4) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col5).normalize(:c), "Form C - Col 4 has to be C(5) - #{comment}" end end @@ -63,12 +59,12 @@ module ConformanceTest # # NFD # c3 == NFD(c1) == NFD(c2) == NFD(c3) - assert_equal col3.ui, @handler.normalize(col1, :d).ui, "Form D - Col 3 has to be NFD(1) - #{comment}" - assert_equal col3.ui, @handler.normalize(col2, :d).ui, "Form D - Col 3 has to be NFD(2) - #{comment}" - assert_equal col3.ui, @handler.normalize(col3, :d).ui, "Form D - Col 3 has to be NFD(3) - #{comment}" + assert_equal_codepoints col3, @proxy.new(col1).normalize(:d), "Form D - Col 3 has to be NFD(1) - #{comment}" + assert_equal_codepoints col3, @proxy.new(col2).normalize(:d), "Form D - Col 3 has to be NFD(2) - #{comment}" + assert_equal_codepoints col3, @proxy.new(col3).normalize(:d), "Form D - Col 3 has to be NFD(3) - #{comment}" # c5 == NFD(c4) == NFD(c5) - assert_equal col5.ui, @handler.normalize(col4, :d).ui, "Form D - Col 5 has to be NFD(4) - #{comment}" - assert_equal col5.ui, @handler.normalize(col5, :d).ui, "Form D - Col 5 has to be NFD(5) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col4).normalize(:d), "Form D - Col 5 has to be NFD(4) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col5).normalize(:d), "Form D - Col 5 has to be NFD(5) - #{comment}" end end @@ -78,11 +74,11 @@ module ConformanceTest # # NFKC # c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5) - assert_equal col4.ui, @handler.normalize(col1, :kc).ui, "Form D - Col 4 has to be NFKC(1) - #{comment}" - assert_equal col4.ui, @handler.normalize(col2, :kc).ui, "Form D - Col 4 has to be NFKC(2) - #{comment}" - assert_equal col4.ui, @handler.normalize(col3, :kc).ui, "Form D - Col 4 has to be NFKC(3) - #{comment}" - assert_equal col4.ui, @handler.normalize(col4, :kc).ui, "Form D - Col 4 has to be NFKC(4) - #{comment}" - assert_equal col4.ui, @handler.normalize(col5, :kc).ui, "Form D - Col 4 has to be NFKC(5) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col1).normalize(:kc), "Form D - Col 4 has to be NFKC(1) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col2).normalize(:kc), "Form D - Col 4 has to be NFKC(2) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col3).normalize(:kc), "Form D - Col 4 has to be NFKC(3) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col4).normalize(:kc), "Form D - Col 4 has to be NFKC(4) - #{comment}" + assert_equal_codepoints col4, @proxy.new(col5).normalize(:kc), "Form D - Col 4 has to be NFKC(5) - #{comment}" end end @@ -92,11 +88,11 @@ module ConformanceTest # # NFKD # c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5) - assert_equal col5.ui, @handler.normalize(col1, :kd).ui, "Form KD - Col 5 has to be NFKD(1) - #{comment}" - assert_equal col5.ui, @handler.normalize(col2, :kd).ui, "Form KD - Col 5 has to be NFKD(2) - #{comment}" - assert_equal col5.ui, @handler.normalize(col3, :kd).ui, "Form KD - Col 5 has to be NFKD(3) - #{comment}" - assert_equal col5.ui, @handler.normalize(col4, :kd).ui, "Form KD - Col 5 has to be NFKD(4) - #{comment}" - assert_equal col5.ui, @handler.normalize(col5, :kd).ui, "Form KD - Col 5 has to be NFKD(5) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col1).normalize(:kd), "Form KD - Col 5 has to be NFKD(1) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col2).normalize(:kd), "Form KD - Col 5 has to be NFKD(2) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col3).normalize(:kd), "Form KD - Col 5 has to be NFKD(3) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col4).normalize(:kd), "Form KD - Col 5 has to be NFKD(4) - #{comment}" + assert_equal_codepoints col5, @proxy.new(col5).normalize(:kd), "Form KD - Col 5 has to be NFKD(5) - #{comment}" end end @@ -104,7 +100,7 @@ module ConformanceTest def each_line_of_norm_tests(&block) lines = 0 max_test_lines = 0 # Don't limit below 38, because that's the header of the testfile - File.open(File.dirname(__FILE__) + '/cache' + UNIDATA_FILE, 'r') do | f | + File.open(File.join(CACHE_DIR, UNIDATA_FILE), 'r') do | f | until f.eof? || (max_test_lines > 38 and lines > max_test_lines) lines += 1 line = f.gets.chomp! @@ -122,25 +118,8 @@ module ConformanceTest end end end -end - -begin - require_library_or_gem('utf8proc_native') - require 'active_record/multibyte/handlers/utf8_handler_proc' - class ConformanceTestProc < Test::Unit::TestCase - include ConformanceTest - def setup - @handler = ::ActiveSupport::Multibyte::Handlers::UTF8HandlerProc + + def inspect_codepoints(str) + str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ') end - end -rescue LoadError -end - -class ConformanceTestPure < Test::Unit::TestCase - include ConformanceTest - def setup - @handler = ::ActiveSupport::Multibyte::Handlers::UTF8Handler - end -end - -end +end \ No newline at end of file diff --git a/activesupport/test/multibyte_handler_test.rb b/activesupport/test/multibyte_handler_test.rb deleted file mode 100644 index 5575ecc..0000000 --- a/activesupport/test/multibyte_handler_test.rb +++ /dev/null @@ -1,372 +0,0 @@ -# encoding: utf-8 -require 'abstract_unit' - -if RUBY_VERSION < '1.9' - -$KCODE = 'UTF8' - -class String - # Unicode Inspect returns the codepoints of the string in hex - def ui - "#{self} " + ("[%s]" % unpack("U*").map{|cp| cp.to_s(16) }.join(' ')) - end unless ''.respond_to?(:ui) -end - -module UTF8HandlingTest - - def common_setup - # This is an ASCII string with some russian strings and a ligature. It's nicely calibrated, because - # slicing it at some specific bytes will kill your characters if you use standard Ruby routines. - # It has both capital and standard letters, so that we can test case conversions easily. - # It has 26 characters and 28 when the ligature gets split during normalization. - @string = "Abcd Блå ffi бла бла бла бла" - @string_kd = "Abcd Блå ffi бла бла бла бла" - @string_kc = "Abcd Блå ffi бла бла бла бла" - @string_c = "Abcd Блå ffi бла бла бла бла" - @string_d = "Abcd Блå ffi бла бла бла бла" - @bytestring = "\270\236\010\210\245" # Not UTF-8 - - # Characters from the character classes as described in UAX #29 - @character_from_class = { - :l => 0x1100, :v => 0x1160, :t => 0x11A8, :lv => 0xAC00, :lvt => 0xAC01, :cr => 0x000D, :lf => 0x000A, - :extend => 0x094D, :n => 0x64 - } - end - - def test_utf8_recognition - assert ActiveSupport::Multibyte::Handlers::UTF8Handler.consumes?(@string), - "Should recognize as a valid UTF-8 string" - assert !ActiveSupport::Multibyte::Handlers::UTF8Handler.consumes?(@bytestring), "This is bytestring, not UTF-8" - end - - def test_simple_normalization - # Normalization of DEVANAGARI LETTER QA breaks when composition exclusion isn't used correctly - assert_equal [0x915, 0x93c].pack('U*').ui, [0x915, 0x93c].pack('U*').chars.normalize(:c).to_s.ui - - null_byte_str = "Test\0test" - - assert_equal '', @handler.normalize(''), "Empty string should not break things" - assert_equal null_byte_str.ui, @handler.normalize(null_byte_str, :kc).ui, "Null byte should remain" - assert_equal null_byte_str.ui, @handler.normalize(null_byte_str, :c).ui, "Null byte should remain" - assert_equal null_byte_str.ui, @handler.normalize(null_byte_str, :d).ui, "Null byte should remain" - assert_equal null_byte_str.ui, @handler.normalize(null_byte_str, :kd).ui, "Null byte should remain" - assert_equal null_byte_str.ui, @handler.decompose(null_byte_str).ui, "Null byte should remain" - assert_equal null_byte_str.ui, @handler.compose(null_byte_str).ui, "Null byte should remain" - - comp_str = [ - 44, # LATIN CAPITAL LETTER D - 307, # COMBINING DOT ABOVE - 328, # COMBINING OGONEK - 323 # COMBINING DOT BELOW - ].pack("U*") - norm_str_KC = [44,105,106,328,323].pack("U*") - norm_str_C = [44,307,328,323].pack("U*") - norm_str_D = [44,307,110,780,78,769].pack("U*") - norm_str_KD = [44,105,106,110,780,78,769].pack("U*") - - assert_equal norm_str_KC.ui, @handler.normalize(comp_str, :kc).ui, "Should normalize KC" - assert_equal norm_str_C.ui, @handler.normalize(comp_str, :c).ui, "Should normalize C" - assert_equal norm_str_D.ui, @handler.normalize(comp_str, :d).ui, "Should normalize D" - assert_equal norm_str_KD.ui, @handler.normalize(comp_str, :kd).ui, "Should normalize KD" - - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.normalize(@bytestring) } - end - - # Test for the Public Review Issue #29, bad explanation of composition might lead to a - # bad implementation: http://www.unicode.org/review/pr-29.html - def test_normalization_C_pri_29 - [ - [0x0B47, 0x0300, 0x0B3E], - [0x1100, 0x0300, 0x1161] - ].map { |c| c.pack('U*') }.each do |c| - assert_equal c.ui, @handler.normalize(c, :c).ui, "Composition is implemented incorrectly" - end - end - - def test_casefolding - simple_str = "abCdef" - simple_str_upcase = "ABCDEF" - simple_str_downcase = "abcdef" - - assert_equal '', @handler.downcase(@handler.upcase('')), "Empty string should not break things" - assert_equal simple_str_upcase, @handler.upcase(simple_str), "should upcase properly" - assert_equal simple_str_downcase, @handler.downcase(simple_str), "should downcase properly" - assert_equal simple_str_downcase, @handler.downcase(@handler.upcase(simple_str_downcase)), "upcase and downcase should be mirrors" - - rus_str = "аБвгд\0f" - rus_str_upcase = "АБВГД\0F" - rus_str_downcase = "абвгд\0f" - assert_equal rus_str_upcase, @handler.upcase(rus_str), "should upcase properly honoring null-byte" - assert_equal rus_str_downcase, @handler.downcase(rus_str), "should downcase properly honoring null-byte" - - jap_str = "の埋め込み化対応はほぼ完成" - assert_equal jap_str, @handler.upcase(jap_str), "Japanse has no upcase, should remain unchanged" - assert_equal jap_str, @handler.downcase(jap_str), "Japanse has no downcase, should remain unchanged" - - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.upcase(@bytestring) } - end - - def test_capitalize - { 'аБвг аБвг' => 'Абвг абвг', - 'аБвг АБВГ' => 'Абвг абвг', - 'АБВГ АБВГ' => 'Абвг абвг', - '' => '' }.each do |f,t| - assert_equal t, @handler.capitalize(f), "Capitalize should work as expected" - end - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.capitalize(@bytestring) } - end - - def test_translate_offset - str = "Блaå" # [2, 2, 1, 2] bytes - assert_equal 0, @handler.translate_offset('', 0), "Offset for an empty string makes no sense, return 0" - assert_equal 0, @handler.translate_offset(str, 0), "First character, first byte" - assert_equal 0, @handler.translate_offset(str, 1), "First character, second byte" - assert_equal 1, @handler.translate_offset(str, 2), "Second character, third byte" - assert_equal 1, @handler.translate_offset(str, 3), "Second character, fourth byte" - assert_equal 2, @handler.translate_offset(str, 4), "Third character, fifth byte" - assert_equal 3, @handler.translate_offset(str, 5), "Fourth character, sixth byte" - assert_equal 3, @handler.translate_offset(str, 6), "Fourth character, seventh byte" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.translate_offset(@bytestring, 3) } - end - - def test_insert - assert_equal '', @handler.insert('', 0, ''), "Empty string should not break things" - assert_equal "Abcd Блå ffiБУМ бла бла бла бла", @handler.insert(@string, 10, "БУМ"), - "Text should be inserted at right codepoints" - assert_equal "Abcd Блå ffiБУМ бла бла бла бла", @string, "Insert should be destructive" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) do - @handler.insert(@bytestring, 2, "\210") - end - end - - def test_reverse - str = "wБлåa \n" - rev = "\n aåлБw" - assert_equal '', @handler.reverse(''), "Empty string shouldn't change" - assert_equal rev.ui, @handler.reverse(str).ui, "Should reverse properly" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.reverse(@bytestring) } - end - - def test_size - assert_equal 0, @handler.size(''), "Empty string has size 0" - assert_equal 26, @handler.size(@string), "String length should be 26" - assert_equal 26, @handler.length(@string), "String length method should be properly aliased" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.size(@bytestring) } - end - - def test_slice - assert_equal 0x41, @handler.slice(@string, 0), "Singular characters should return codepoints" - assert_equal 0xE5, @handler.slice(@string, 7), "Singular characters should return codepoints" - assert_equal nil, @handler.slice('', -1..1), "Broken range should return nil" - assert_equal '', @handler.slice('', 0..10), "Empty string should not break things" - assert_equal "d Блå ffi", @handler.slice(@string, 3..9), "Unicode characters have to be returned" - assert_equal "d Блå ffi", @handler.slice(@string, 3, 7), "Unicode characters have to be returned" - assert_equal "A", @handler.slice(@string, 0, 1), "Slicing from an offset should return characters" - assert_equal " Блå ffi ", @handler.slice(@string, 4..10), "Unicode characters have to be returned" - assert_equal "ffi бла", @handler.slice(@string, /ffi бла/u), "Slicing on Regexps should be supported" - assert_equal "ffi бла", @handler.slice(@string, /ffi \w\wа/u), "Slicing on Regexps should be supported" - assert_equal nil, @handler.slice(@string, /unknown/u), "Slicing on Regexps with no match should return nil" - assert_equal "ffi бла", @handler.slice(@string, /(ffi бла)/u,1), "Slicing on Regexps with a match group should be supported" - assert_equal nil, @handler.slice(@string, /(ffi)/u,2), "Slicing with a Regexp and asking for an invalid match group should return nil" - assert_equal "", @handler.slice(@string, 7..6), "Range is empty, should return an empty string" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.slice(@bytestring, 2..3) } - assert_raise(TypeError, "With 2 args, should raise TypeError for non-Numeric or Regexp first argument") { @handler.slice(@string, 2..3, 1) } - assert_raise(TypeError, "With 2 args, should raise TypeError for non-Numeric or Regexp second argument") { @handler.slice(@string, 1, 2..3) } - assert_raise(ArgumentError, "Should raise ArgumentError when there are more than 2 args") { @handler.slice(@string, 1, 1, 1) } - end - - def test_grapheme_cluster_length - assert_equal 0, @handler.g_length(''), "String should count 0 grapheme clusters" - assert_equal 2, @handler.g_length([0x0924, 0x094D, 0x0930].pack('U*')), "String should count 2 grapheme clusters" - assert_equal 1, @handler.g_length(string_from_classes(%w(cr lf))), "Don't cut between CR and LF" - assert_equal 1, @handler.g_length(string_from_classes(%w(l l))), "Don't cut between L" - assert_equal 1, @handler.g_length(string_from_classes(%w(l v))), "Don't cut between L and V" - assert_equal 1, @handler.g_length(string_from_classes(%w(l lv))), "Don't cut between L and LV" - assert_equal 1, @handler.g_length(string_from_classes(%w(l lvt))), "Don't cut between L and LVT" - assert_equal 1, @handler.g_length(string_from_classes(%w(lv v))), "Don't cut between LV and V" - assert_equal 1, @handler.g_length(string_from_classes(%w(lv t))), "Don't cut between LV and T" - assert_equal 1, @handler.g_length(string_from_classes(%w(v v))), "Don't cut between V and V" - assert_equal 1, @handler.g_length(string_from_classes(%w(v t))), "Don't cut between V and T" - assert_equal 1, @handler.g_length(string_from_classes(%w(lvt t))), "Don't cut between LVT and T" - assert_equal 1, @handler.g_length(string_from_classes(%w(t t))), "Don't cut between T and T" - assert_equal 1, @handler.g_length(string_from_classes(%w(n extend))), "Don't cut before Extend" - assert_equal 2, @handler.g_length(string_from_classes(%w(n n))), "Cut between normal characters" - assert_equal 3, @handler.g_length(string_from_classes(%w(n cr lf n))), "Don't cut between CR and LF" - assert_equal 2, @handler.g_length(string_from_classes(%w(n l v t))), "Don't cut between L, V and T" - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.g_length(@bytestring) } - end - - def test_index - s = "Καλημέρα κόσμε!" - assert_equal 0, @handler.index('', ''), "The empty string is always found at the beginning of the string" - assert_equal 0, @handler.index('haystack', ''), "The empty string is always found at the beginning of the string" - assert_equal 0, @handler.index(s, 'Κ'), "Greek K is at 0" - assert_equal 1, @handler.index(s, 'α'), "Greek Alpha is at 1" - - assert_equal nil, @handler.index(@bytestring, 'a') - assert_raise(ActiveSupport::Multibyte::Handlers::EncodingError) { @handler.index(@bytestring, "\010") } - end - - def test_indexed_insert - s = "Καλη!" - @handler[s, 2] = "a" - assert_equal "Καaη!", s - @handler[s, 2] = "ηη" - assert_equal "Καηηη!", s - assert_raises(IndexError) { @handler[s, 10] = 'a' } - assert_equal "Καηηη!", s - @handler[s, 2] = 32 - assert_equal "Κα ηη!", s - @handler[s, 3, 2] = "λλλ" - assert_equal "Κα λλλ!", s - @handler[s, 1, 0] = "λ" - assert_equal "Κλα λλλ!", s - assert_raises(IndexError) { @handler[s, 10, 4] = 'a' } - assert_equal "Κλα λλλ!", s - @handler[s, 4..6] = "ηη" - assert_equal "Κλα ηη!", s - assert_raises(RangeError) { @handler[s, 10..12] = 'a' } - assert_equal "Κλα ηη!", s - @handler[s, /ηη/] = "λλλ" - assert_equal "Κλα λλλ!", s - assert_raises(IndexError) { @handler[s, /ii/] = 'a' } - assert_equal "Κλα λλλ!", s - @handler[s, /(λλ)(.)/, 2] = "α" - assert_equal "Κλα λλα!", s - assert_raises(IndexError) { @handler[s, /()/, 10] = 'a' } - assert_equal "Κλα λλα!", s - @handler[s, "α"] = "η" - assert_equal "Κλη λλα!", s - @handler[s, "λλ"] = "ααα" - assert_equal "Κλη αααα!", s - end - - def test_rjust - s = "Καη" - assert_raises(ArgumentError) { @handler.rjust(s, 10, '') } - assert_raises(ArgumentError) { @handler.rjust(s) } - assert_equal "Καη", @handler.rjust(s, -3) - assert_equal "Καη", @handler.rjust(s, 0) - assert_equal "Καη", @handler.rjust(s, 3) - assert_equal " Καη", @handler.rjust(s, 5) - assert_equal " Καη", @handler.rjust(s, 7) - assert_equal "----Καη", @handler.rjust(s, 7, '-') - assert_equal "ααααΚαη", @handler.rjust(s, 7, 'α') - assert_equal "abaΚαη", @handler.rjust(s, 6, 'ab') - assert_equal "αηαΚαη", @handler.rjust(s, 6, 'αη') - end - - def test_ljust - s = "Καη" - assert_raises(ArgumentError) { @handler.ljust(s, 10, '') } - assert_raises(ArgumentError) { @handler.ljust(s) } - assert_equal "Καη", @handler.ljust(s, -3) - assert_equal "Καη", @handler.ljust(s, 0) - assert_equal "Καη", @handler.ljust(s, 3) - assert_equal "Καη ", @handler.ljust(s, 5) - assert_equal "Καη ", @handler.ljust(s, 7) - assert_equal "Καη----", @handler.ljust(s, 7, '-') - assert_equal "Καηαααα", @handler.ljust(s, 7, 'α') - assert_equal "Καηaba", @handler.ljust(s, 6, 'ab') - assert_equal "Καηαηα", @handler.ljust(s, 6, 'αη') - end - - def test_center - s = "Καη" - assert_raises(ArgumentError) { @handler.center(s, 10, '') } - assert_raises(ArgumentError) { @handler.center(s) } - assert_equal "Καη", @handler.center(s, -3) - assert_equal "Καη", @handler.center(s, 0) - assert_equal "Καη", @handler.center(s, 3) - assert_equal "Καη ", @handler.center(s, 4) - assert_equal " Καη ", @handler.center(s, 5) - assert_equal " Καη ", @handler.center(s, 6) - assert_equal "--Καη--", @handler.center(s, 7, '-') - assert_equal "--Καη---", @handler.center(s, 8, '-') - assert_equal "ααΚαηαα", @handler.center(s, 7, 'α') - assert_equal "ααΚαηααα", @handler.center(s, 8, 'α') - assert_equal "aΚαηab", @handler.center(s, 6, 'ab') - assert_equal "abΚαηab", @handler.center(s, 7, 'ab') - assert_equal "ababΚαηabab", @handler.center(s, 11, 'ab') - assert_equal "αΚαηαη", @handler.center(s, 6, 'αη') - assert_equal "αηΚαηαη", @handler.center(s, 7, 'αη') - end - - def test_strip - # A unicode aware version of strip should strip all 26 types of whitespace. This includes the NO BREAK SPACE - # aka BOM (byte order mark). The byte order mark has no place in UTF-8 because it's used to detect LE and BE. - b = "\n" + [ - 32, # SPACE - 8195, # EM SPACE - 8199, # FIGURE SPACE, - 8201, # THIN SPACE - 8202, # HAIR SPACE - 65279, # NO BREAK SPACE (ZW) - ].pack('U*') - m = "word блин\n\n\n word" - e = [ - 65279, # NO BREAK SPACE (ZW) - 8201, # THIN SPACE - 8199, # FIGURE SPACE, - 32, # SPACE - ].pack('U*') - string = b+m+e - - assert_equal '', @handler.strip(''), "Empty string should stay empty" - assert_equal m+e, @handler.lstrip(string), "Whitespace should be gone on the left" - assert_equal b+m, @handler.rstrip(string), "Whitespace should be gone on the right" - assert_equal m, @handler.strip(string), "Whitespace should be stripped on both sides" - - bs = "\n #{@bytestring} \n\n" - assert_equal @bytestring, @handler.strip(bs), "Invalid unicode strings should still strip" - end - - def test_tidy_bytes - result = [0xb8, 0x17e, 0x8, 0x2c6, 0xa5].pack('U*') - assert_equal result, @handler.tidy_bytes(@bytestring) - assert_equal "a#{result}a", @handler.tidy_bytes('a' + @bytestring + 'a'), - 'tidy_bytes should leave surrounding characters intact' - assert_equal "é#{result}é", @handler.tidy_bytes('é' + @bytestring + 'é'), - 'tidy_bytes should leave surrounding characters intact' - assert_nothing_raised { @handler.tidy_bytes(@bytestring).unpack('U*') } - - assert_equal "\xC3\xA7", @handler.tidy_bytes("\xE7") # iso_8859_1: small c cedilla - assert_equal "\xC2\xA9", @handler.tidy_bytes("\xA9") # iso_8859_1: copyright symbol - assert_equal "\xE2\x80\x9C", @handler.tidy_bytes("\x93") # win_1252: left smart quote - assert_equal "\xE2\x82\xAC", @handler.tidy_bytes("\x80") # win_1252: euro - assert_equal "\x00", @handler.tidy_bytes("\x00") # null char - assert_equal [0xfffd].pack('U'), @handler.tidy_bytes("\xef\xbf\xbd") # invalid char - end - - protected - - def string_from_classes(classes) - classes.collect do |k| - @character_from_class[k.intern] - end.pack('U*') - end -end - - -begin - require_library_or_gem('utf8proc_native') - require 'active_record/multibyte/handlers/utf8_handler_proc' - class UTF8HandlingTestProc < Test::Unit::TestCase - include UTF8HandlingTest - def setup - common_setup - @handler = ::ActiveSupport::Multibyte::Handlers::UTF8HandlerProc - end - end -rescue LoadError -end - -class UTF8HandlingTestPure < Test::Unit::TestCase - include UTF8HandlingTest - def setup - common_setup - @handler = ::ActiveSupport::Multibyte::Handlers::UTF8Handler - end -end - -end diff --git a/activesupport/test/multibyte_unicode_database_test.rb b/activesupport/test/multibyte_unicode_database_test.rb new file mode 100644 index 0000000..fb415e0 --- /dev/null +++ b/activesupport/test/multibyte_unicode_database_test.rb @@ -0,0 +1,28 @@ +# encoding: utf-8 + +require 'abstract_unit' + +uses_mocha "MultibyteUnicodeDatabaseTest" do + +class MultibyteUnicodeDatabaseTest < Test::Unit::TestCase + + def setup + @ucd = ActiveSupport::Multibyte::UnicodeDatabase.new + end + + ActiveSupport::Multibyte::UnicodeDatabase::ATTRIBUTES.each do |attribute| + define_method "test_lazy_loading_on_attribute_access_of_#{attribute}" do + @ucd.expects(:load) + @ucd.send(attribute) + end + end + + def test_load + @ucd.load + ActiveSupport::Multibyte::UnicodeDatabase::ATTRIBUTES.each do |attribute| + assert @ucd.send(attribute).length > 1 + end + end +end + +end \ No newline at end of file -- 1.6.0 From e1083b739e7fa600d5f173e89f834f11e90495bf Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 12:42:23 +0200 Subject: [PATCH] Add a test for ActiveSupport::Multibyte::Chars.consumes?. --- activesupport/test/multibyte_chars_test.rb | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 31b8f1b..5029d2e 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -29,7 +29,8 @@ class MultibyteCharsTest < Test::Unit::TestCase include MultibyteTest def setup - @chars = ActiveSupport::Multibyte::Chars.new UNICODE_STRING + @proxy_class = ActiveSupport::Multibyte::Chars + @chars = @proxy_class.new UNICODE_STRING end def test_wraps_the_original_string @@ -70,6 +71,12 @@ class MultibyteCharsTest < Test::Unit::TestCase assert_equal 'ab', 'a'.mb_chars << 'b'.mb_chars end + def test_consumes_utf8_strings + assert @proxy_class.consumes?(UNICODE_STRING) + assert @proxy_class.consumes?(ASCII_STRING) + assert !@proxy_class.consumes?(BYTE_STRING) + end + if RUBY_VERSION < '1.9' def test_concatenation_should_return_a_proxy_class_instance assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars + 'b').class -- 1.6.0 From c1e6c7b4a0e1f386c5fbf5054f9632a4ec694cf7 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 14:56:29 +0200 Subject: [PATCH] Move with_kcode helper to abstract_unit. Add tests for multibyte string extensions. --- activesupport/test/abstract_unit.rb | 15 ++++++- activesupport/test/core_ext/string_ext_test.rb | 53 +++++++++++++++++++++--- activesupport/test/json/encoding_test.rb | 12 ----- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index f39f264..a698bea 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -27,4 +27,17 @@ unless defined? uses_mocha end # Show backtraces for deprecated behavior for quicker cleanup. -ActiveSupport::Deprecation.debug = true \ No newline at end of file +ActiveSupport::Deprecation.debug = true + +def with_kcode(code) + if RUBY_VERSION < '1.9' + begin + old_kcode, $KCODE = $KCODE, code + yield + ensure + $KCODE = old_kcode + end + else + yield + end +end \ No newline at end of file diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index c0decf2..fe5ce27 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -191,13 +191,12 @@ class StringInflectionsTest < Test::Unit::TestCase if RUBY_VERSION < '1.9' def test_each_char_with_utf8_string_when_kcode_is_utf8 - old_kcode, $KCODE = $KCODE, 'UTF8' - '€2.99'.each_char do |char| - assert_not_equal 1, char.length - break + with_kcode('UTF8') do + '€2.99'.each_char do |char| + assert_not_equal 1, char.length + break + end end - ensure - $KCODE = old_kcode end end end @@ -206,4 +205,46 @@ class StringBehaviourTest < Test::Unit::TestCase def test_acts_like_string assert 'Bambi'.acts_like_string? end +end + +class CoreExtStringMultibyteTest < Test::Unit::TestCase + UNICODE_STRING = 'こにちわ' + ASCII_STRING = 'ohayo' + BYTE_STRING = "\270\236\010\210\245" + + def test_core_ext_adds_mb_chars + assert UNICODE_STRING.respond_to?(:mb_chars) + end + + def test_string_should_recognize_utf8_strings + assert UNICODE_STRING.is_utf8? + assert ASCII_STRING.is_utf8? + assert !BYTE_STRING.is_utf8? + end + + if RUBY_VERSION < '1.8.7' + def test_core_ext_adds_chars + assert UNICODE_STRING.respond_to?(:chars) + end + end + + if RUBY_VERSION < '1.9' + def test_mb_chars_returns_self_when_kcode_not_set + with_kcode('none') do + assert UNICODE_STRING.mb_chars.kind_of?(String) + end + end + + def test_mb_chars_returns_an_instance_of_the_chars_proxy_when_kcode_utf8 + with_kcode('UTF8') do + assert UNICODE_STRING.mb_chars.kind_of?(ActiveSupport::Multibyte.proxy_class) + end + end + end + + if RUBY_VERSION >= '1.9' + def test_mb_chars_returns_string + assert UNICODE_STRING.mb_chars.kind_of?(String) + end + end end \ No newline at end of file diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 38bb8f3..497f028 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -101,18 +101,6 @@ class TestJSONEncoding < Test::Unit::TestCase end protected - def with_kcode(code) - if RUBY_VERSION < '1.9' - begin - old_kcode, $KCODE = $KCODE, 'UTF8' - yield - ensure - $KCODE = old_kcode - end - else - yield - end - end def object_keys(json_object) json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort -- 1.6.0 From 3e263a241a38c985bd9e1abf146f6e495d8ae7cd Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 14:59:11 +0200 Subject: [PATCH] Change remaining calls to .chars to .mb_chars. --- .../lib/active_support/core_ext/string/access.rb | 10 +++++----- .../lib/active_support/multibyte/chars.rb | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/string/access.rb b/activesupport/lib/active_support/core_ext/string/access.rb index 1a949c0..7fb21fa 100644 --- a/activesupport/lib/active_support/core_ext/string/access.rb +++ b/activesupport/lib/active_support/core_ext/string/access.rb @@ -11,7 +11,7 @@ module ActiveSupport #:nodoc: # "hello".at(4) # => "o" # "hello".at(10) # => nil def at(position) - chars[position, 1].to_s + mb_chars[position, 1].to_s end # Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character). @@ -21,7 +21,7 @@ module ActiveSupport #:nodoc: # "hello".from(2) # => "llo" # "hello".from(10) # => nil def from(position) - chars[position..-1].to_s + mb_chars[position..-1].to_s end # Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character). @@ -31,7 +31,7 @@ module ActiveSupport #:nodoc: # "hello".to(2) # => "hel" # "hello".to(10) # => "hello" def to(position) - chars[0..position].to_s + mb_chars[0..position].to_s end # Returns the first character of the string or the first +limit+ characters. @@ -41,7 +41,7 @@ module ActiveSupport #:nodoc: # "hello".first(2) # => "he" # "hello".first(10) # => "hello" def first(limit = 1) - chars[0..(limit - 1)].to_s + mb_chars[0..(limit - 1)].to_s end # Returns the last character of the string or the last +limit+ characters. @@ -51,7 +51,7 @@ module ActiveSupport #:nodoc: # "hello".last(2) # => "lo" # "hello".last(10) # => "hello" def last(limit = 1) - (chars[(-limit)..-1] || self).to_s + (mb_chars[(-limit)..-1] || self).to_s end end else diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index c05419b..cd0993d 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -9,12 +9,12 @@ module ActiveSupport #:nodoc: # String methods are proxied through the Chars object, and can be accessed through the +mb_chars+ method. Methods # which would normally return a String object now return a Chars object so methods can be chained. # - # "The Perfect String ".chars.downcase.strip.normalize #=> "the perfect string" + # "The Perfect String ".mb_chars.downcase.strip.normalize #=> "the perfect string" # # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them. # - # bad.explicit_checking_method "T".chars.downcase.to_s + # bad.explicit_checking_method "T".mb_chars.downcase.to_s # # The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different # encodings you can write your own multibyte string handler and configure it through @@ -213,12 +213,12 @@ module ActiveSupport #:nodoc: # Example: # # s = "Müller" - # s.chars[2] = "e" # Replace character with offset 2 + # s.mb_chars[2] = "e" # Replace character with offset 2 # s # #=> "Müeler" # # s = "Müller" - # s.chars[1, 2] = "ö" # Replace 2 characters at character offset 1 + # s.mb_chars[1, 2] = "ö" # Replace 2 characters at character offset 1 # s # #=> "Möler" def []=(*args) @@ -253,10 +253,10 @@ module ActiveSupport #:nodoc: # # Example: # - # "¾ cup".chars.rjust(8).to_s + # "¾ cup".mb_chars.rjust(8).to_s # #=> " ¾ cup" # - # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace + # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace # #=> "   ¾ cup" def rjust(integer, padstr=' ') justify(integer, :right, padstr) @@ -266,10 +266,10 @@ module ActiveSupport #:nodoc: # # Example: # - # "¾ cup".chars.rjust(8).to_s + # "¾ cup".mb_chars.rjust(8).to_s # #=> "¾ cup " # - # "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace + # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace # #=> "¾ cup   " def ljust(integer, padstr=' ') justify(integer, :left, padstr) @@ -279,10 +279,10 @@ module ActiveSupport #:nodoc: # # Example: # - # "¾ cup".chars.center(8).to_s + # "¾ cup".mb_chars.center(8).to_s # #=> " ¾ cup " # - # "¾ cup".chars.center(8, " ").to_s # Use non-breaking whitespace + # "¾ cup".mb_chars.center(8, " ").to_s # Use non-breaking whitespace # #=> " ¾ cup  " def center(integer, padstr=' ') justify(integer, :center, padstr) -- 1.6.0 From 6721153a15f6605c56bb2a960f5f741c4ad51507 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 15:44:06 +0200 Subject: [PATCH] Remove all whitespace from empty lines. --- activesupport/test/core_ext/string_ext_test.rb | 4 +- activesupport/test/multibyte_conformance.rb | 24 ++++++++++---------- .../test/multibyte_unicode_database_test.rb | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index fe5ce27..ee063ac 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -94,13 +94,13 @@ class StringInflectionsTest < Test::Unit::TestCase assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time assert_equal Time.local_time(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time(:local) end - + def test_string_to_datetime assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_datetime assert_equal 0, "2039-02-27 23:50".to_datetime.offset # use UTC offset assert_equal ::Date::ITALY, "2039-02-27 23:50".to_datetime.start # use Ruby's default start value end - + def test_string_to_date assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date end diff --git a/activesupport/test/multibyte_conformance.rb b/activesupport/test/multibyte_conformance.rb index fe6cd70..87e2cd0 100644 --- a/activesupport/test/multibyte_conformance.rb +++ b/activesupport/test/multibyte_conformance.rb @@ -23,21 +23,21 @@ end class MultibyteConformanceTest < Test::Unit::TestCase include MultibyteTest - + UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd" UNIDATA_FILE = '/NormalizationTest.txt' CACHE_DIR = File.join(Dir.tmpdir, 'cache') - + def setup FileUtils.mkdir_p(CACHE_DIR) Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE) @proxy = ActiveSupport::Multibyte::Chars end - + def test_normalizations_C each_line_of_norm_tests do |*cols| col1, col2, col3, col4, col5, comment = *cols - + # CONFORMANCE: # 1. The following invariants must be true for all conformant implementations # @@ -52,7 +52,7 @@ class MultibyteConformanceTest < Test::Unit::TestCase assert_equal_codepoints col4, @proxy.new(col5).normalize(:c), "Form C - Col 4 has to be C(5) - #{comment}" end end - + def test_normalizations_D each_line_of_norm_tests do |*cols| col1, col2, col3, col4, col5, comment = *cols @@ -67,7 +67,7 @@ class MultibyteConformanceTest < Test::Unit::TestCase assert_equal_codepoints col5, @proxy.new(col5).normalize(:d), "Form D - Col 5 has to be NFD(5) - #{comment}" end end - + def test_normalizations_KC each_line_of_norm_tests do | *cols | col1, col2, col3, col4, col5, comment = *cols @@ -81,7 +81,7 @@ class MultibyteConformanceTest < Test::Unit::TestCase assert_equal_codepoints col4, @proxy.new(col5).normalize(:kc), "Form D - Col 4 has to be NFKC(5) - #{comment}" end end - + def test_normalizations_KD each_line_of_norm_tests do | *cols | col1, col2, col3, col4, col5, comment = *cols @@ -95,7 +95,7 @@ class MultibyteConformanceTest < Test::Unit::TestCase assert_equal_codepoints col5, @proxy.new(col5).normalize(:kd), "Form KD - Col 5 has to be NFKD(5) - #{comment}" end end - + protected def each_line_of_norm_tests(&block) lines = 0 @@ -105,20 +105,20 @@ class MultibyteConformanceTest < Test::Unit::TestCase lines += 1 line = f.gets.chomp! next if (line.empty? || line =~ /^\#/) - + cols, comment = line.split("#") cols = cols.split(";").map{|e| e.strip}.reject{|e| e.empty? } next unless cols.length == 5 - + # codepoints are in hex in the test suite, pack wants them as integers cols.map!{|c| c.split.map{|codepoint| codepoint.to_i(16)}.pack("U*") } cols << comment - + yield(*cols) end end end - + def inspect_codepoints(str) str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ') end diff --git a/activesupport/test/multibyte_unicode_database_test.rb b/activesupport/test/multibyte_unicode_database_test.rb index fb415e0..b52250d 100644 --- a/activesupport/test/multibyte_unicode_database_test.rb +++ b/activesupport/test/multibyte_unicode_database_test.rb @@ -16,7 +16,7 @@ class MultibyteUnicodeDatabaseTest < Test::Unit::TestCase @ucd.send(attribute) end end - + def test_load @ucd.load ActiveSupport::Multibyte::UnicodeDatabase::ATTRIBUTES.each do |attribute| -- 1.6.0 From bf832475f295ae3f0c7cc00b3471631eaa30f3e0 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 17:12:49 +0200 Subject: [PATCH] Improve test coverage. Make sure that all methods which normally return a string now return a proxy instance. --- .../lib/active_support/multibyte/chars.rb | 3 +- activesupport/test/multibyte_chars_test.rb | 49 +++++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index cd0993d..27cc3c6 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -246,7 +246,6 @@ module ActiveSupport #:nodoc: result[range] = self.class.u_unpack(replace_by) @wrapped_string.replace(result.pack('U*')) end - self end # Works just like String#rjust, only integer specifies characters instead of bytes. @@ -365,7 +364,7 @@ module ActiveSupport #:nodoc: # Example: # 'über'.mb_chars.capitalize.to_s #=> "Über" def capitalize - (slice(0) || '').upcase + (slice(1..-1) || '').downcase + (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase end # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 5029d2e..6400707 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -48,12 +48,12 @@ class MultibyteCharsTest < Test::Unit::TestCase end def test_forwarded_method_calls_should_return_new_chars_instance - assert @chars.__string_for_multibyte_testing.kind_of?(ActiveSupport::Multibyte::Chars) + assert @chars.__string_for_multibyte_testing.kind_of?(@proxy_class) assert_not_equal @chars.object_id, @chars.__string_for_multibyte_testing.object_id end def test_forwarded_bang_method_calls_should_return_the_original_chars_instance - assert @chars.__string_for_multibyte_testing!.kind_of?(ActiveSupport::Multibyte::Chars) + assert @chars.__string_for_multibyte_testing!.kind_of?(@proxy_class) assert_equal @chars.object_id, @chars.__string_for_multibyte_testing!.object_id end @@ -88,10 +88,10 @@ class MultibyteCharsTest < Test::Unit::TestCase end def test_concatenate_should_return_proxy_instance - assert(('a'.mb_chars + 'b').kind_of?(ActiveSupport::Multibyte::Chars)) - assert(('a'.mb_chars + 'b'.mb_chars).kind_of?(ActiveSupport::Multibyte::Chars)) - assert(('a'.mb_chars << 'b').kind_of?(ActiveSupport::Multibyte::Chars)) - assert(('a'.mb_chars << 'b'.mb_chars).kind_of?(ActiveSupport::Multibyte::Chars)) + assert(('a'.mb_chars + 'b').kind_of?(@proxy_class)) + assert(('a'.mb_chars + 'b'.mb_chars).kind_of?(@proxy_class)) + assert(('a'.mb_chars << 'b').kind_of?(@proxy_class)) + assert(('a'.mb_chars << 'b'.mb_chars).kind_of?(@proxy_class)) end end end @@ -111,7 +111,7 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase if RUBY_VERSION < '1.9' def test_split_should_return_an_array_of_chars_instances @chars.split(//).each do |character| - assert character.kind_of?(ActiveSupport::Multibyte::Chars) + assert character.kind_of?(ActiveSupport::Multibyte.proxy_class) end end @@ -150,6 +150,35 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase end end + def test_identity + assert_equal @chars, @chars + assert @chars.eql?(@chars) + if RUBY_VERSION <= '1.9' + assert !@chars.eql?(UNICODE_STRING) + else + assert @chars.eql?(UNICODE_STRING) + end + end + + def test_string_methods_are_chainable + assert chars('').insert(0, '').kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').rjust(1).kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').ljust(1).kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').center(1).kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').rstrip.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').lstrip.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').strip.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').reverse.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars(' ').slice(0).kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').upcase.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').downcase.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').capitalize.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').normalize.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').decompose.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').compose.kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').tidy_bytes.kind_of?(ActiveSupport::Multibyte.proxy_class) + end + def test_should_be_equal_to_the_wrapped_string assert_equal UNICODE_STRING, @chars assert_equal @chars, UNICODE_STRING @@ -160,6 +189,11 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase assert_not_equal 'other', @chars end + def test_sortability + words = %w(builder armor zebra).map(&:mb_chars).sort + assert_equal %w(armor builder zebra), words + end + def test_should_return_character_offset_for_regexp_matches assert_nil(@chars =~ /wrong/u) assert_equal 0, (@chars =~ /こ/u) @@ -181,6 +215,7 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase end def test_insert_throws_index_error + assert_raises(IndexError) { @chars.insert(-12, 'わ')} assert_raises(IndexError) { @chars.insert(12, 'わ') } end -- 1.6.0 From 354f396e3e98f44e4ad0e2fc31c64bbd9eed9f6c Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 17:37:50 +0200 Subject: [PATCH] Use the chars proxy through .mb_chars instead of .chars in Actionpack. Remove a 1.9 exception for the truncate helper. --- actionpack/lib/action_view/helpers/text_helper.rb | 128 +++++++-------------- 1 files changed, 41 insertions(+), 87 deletions(-) diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index ab1fdc8..4e37114 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -42,65 +42,46 @@ module ActionView output_buffer << string end - if RUBY_VERSION < '1.9' - # Truncates a given +text+ after a given :length if +text+ is longer than :length - # (defaults to 30). The last characters will be replaced with the :omission (defaults to "..."). - # - # ==== Examples - # - # truncate("Once upon a time in a world far far away") - # # => Once upon a time in a world f... - # - # truncate("Once upon a time in a world far far away", :length => 14) - # # => Once upon a... - # - # truncate("And they found that many people were sleeping better.", :length => 25, "(clipped)") - # # => And they found that many (clipped) - # - # truncate("And they found that many people were sleeping better.", :omission => "... (continued)", :length => 15) - # # => And they found... (continued) - # - # You can still use truncate with the old API that accepts the - # +length+ as its optional second and the +ellipsis+ as its - # optional third parameter: - # truncate("Once upon a time in a world far far away", 14) - # # => Once upon a time in a world f... - # - # truncate("And they found that many people were sleeping better.", 15, "... (continued)") - # # => And they found... (continued) - def truncate(text, *args) - options = args.extract_options! - unless args.empty? - ActiveSupport::Deprecation.warn('truncate takes an option hash instead of separate ' + - 'length and omission arguments', caller) - - options[:length] = args[0] || 30 - options[:omission] = args[1] || "..." - end - options.reverse_merge!(:length => 30, :omission => "...") + # Truncates a given +text+ after a given :length if +text+ is longer than :length + # (defaults to 30). The last characters will be replaced with the :omission (defaults to "..."). + # + # ==== Examples + # + # truncate("Once upon a time in a world far far away") + # # => Once upon a time in a world f... + # + # truncate("Once upon a time in a world far far away", :length => 14) + # # => Once upon a... + # + # truncate("And they found that many people were sleeping better.", :length => 25, "(clipped)") + # # => And they found that many (clipped) + # + # truncate("And they found that many people were sleeping better.", :omission => "... (continued)", :length => 15) + # # => And they found... (continued) + # + # You can still use truncate with the old API that accepts the + # +length+ as its optional second and the +ellipsis+ as its + # optional third parameter: + # truncate("Once upon a time in a world far far away", 14) + # # => Once upon a time in a world f... + # + # truncate("And they found that many people were sleeping better.", 15, "... (continued)") + # # => And they found... (continued) + def truncate(text, *args) + options = args.extract_options! + unless args.empty? + ActiveSupport::Deprecation.warn('truncate takes an option hash instead of separate ' + + 'length and omission arguments', caller) - if text - l = options[:length] - options[:omission].chars.length - chars = text.chars - (chars.length > options[:length] ? chars[0...l] + options[:omission] : text).to_s - end + options[:length] = args[0] || 30 + options[:omission] = args[1] || "..." end - else - def truncate(text, *args) #:nodoc: - options = args.extract_options! - unless args.empty? - ActiveSupport::Deprecation.warn('truncate takes an option hash instead of separate ' + - 'length and omission arguments', caller) - - options[:length] = args[0] || 30 - options[:omission] = args[1] || "..." - end - options.reverse_merge!(:length => 30, :omission => "...") + options.reverse_merge!(:length => 30, :omission => "...") - if text - l = options[:length].to_i - options[:omission].length - (text.length > options[:length].to_i ? text[0...l] + options[:omission] : text).to_s - end + if text + l = options[:length] - options[:omission].mb_chars.length + chars = text.mb_chars + (chars.length > options[:length] ? chars[0...l] + options[:omission] : text).to_s end end @@ -140,7 +121,6 @@ module ActionView end end - if RUBY_VERSION < '1.9' # Extracts an excerpt from +text+ that matches the first instance of +phrase+. # The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters # defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+, @@ -179,45 +159,19 @@ module ActionView if text && phrase phrase = Regexp.escape(phrase) - if found_pos = text.chars =~ /(#{phrase})/i + if found_pos = text.mb_chars =~ /(#{phrase})/i start_pos = [ found_pos - options[:radius], 0 ].max - end_pos = [ [ found_pos + phrase.chars.length + options[:radius] - 1, 0].max, text.chars.length ].min + end_pos = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min prefix = start_pos > 0 ? options[:omission] : "" - postfix = end_pos < text.chars.length - 1 ? options[:omission] : "" + postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : "" - prefix + text.chars[start_pos..end_pos].strip + postfix + prefix + text.mb_chars[start_pos..end_pos].strip + postfix else nil end end end - else - def excerpt(text, phrase, *args) #:nodoc: - options = args.extract_options! - unless args.empty? - options[:radius] = args[0] || 100 - options[:omission] = args[1] || "..." - end - options.reverse_merge!(:radius => 100, :omission => "...") - - if text && phrase - phrase = Regexp.escape(phrase) - - if found_pos = text =~ /(#{phrase})/i - start_pos = [ found_pos - options[:radius], 0 ].max - end_pos = [ [ found_pos + phrase.length + options[:radius] - 1, 0].max, text.length ].min - - prefix = start_pos > 0 ? options[:omission] : "" - postfix = end_pos < text.length - 1 ? options[:omission] : "" - - prefix + text[start_pos..end_pos].strip + postfix - else - nil - end - end - end - end # Attempts to pluralize the +singular+ word unless +count+ is 1. If # +plural+ is supplied, it will use that when count is > 1, otherwise -- 1.6.0 From 282855a673f4dcb887ec387633d77983d235e3a6 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Thu, 12 Jun 2008 17:38:45 +0200 Subject: [PATCH] Use the chars proxy through .mb_chars instead of .chars in ActiveRecord. --- activerecord/test/cases/base_test.rb | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 activerecord/test/cases/base_test.rb diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb old mode 100644 new mode 100755 index bda6f34..fb9e743 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1424,8 +1424,8 @@ class BasicsTest < ActiveRecord::TestCase topic = Topic.create(:author_name => str) assert_equal str, topic.author_name - assert_kind_of ActiveSupport::Multibyte::Chars, str.chars - topic = Topic.find_by_author_name(str.chars) + assert_kind_of ActiveSupport::Multibyte.proxy_class, str.mb_chars + topic = Topic.find_by_author_name(str.mb_chars) assert_kind_of Topic, topic assert_equal str, topic.author_name, "The right topic should have been found by name even with name passed as Chars" -- 1.6.0 From 1e29c7c7fcc894a29b58c3d9b2d7a6a49c358bc5 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Fri, 13 Jun 2008 14:27:07 +0200 Subject: [PATCH] Improve documentation. --- .../active_support/core_ext/string/multibyte.rb | 23 ++--- activesupport/lib/active_support/multibyte.rb | 4 +- .../lib/active_support/multibyte/chars.rb | 113 +++++++++++--------- .../lib/active_support/multibyte/exceptions.rb | 1 + 4 files changed, 74 insertions(+), 67 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb index 5a2dc36..3bf79bc 100644 --- a/activesupport/lib/active_support/core_ext/string/multibyte.rb +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -6,7 +6,9 @@ module ActiveSupport #:nodoc: # Implements multibyte methods for easier access to multibyte characters in a String instance. module Multibyte unless '1.9'.respond_to?(:force_encoding) - # +mb_chars+ is a multibyte safe proxy method for string methods. + # == Multibyte proxy + # + # +mb_chars+ is a multibyte safe proxy for string methods. # # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy @@ -19,11 +21,10 @@ module ActiveSupport #:nodoc: # name.mb_chars.reverse.to_s #=> "rellüM sualC" # name.mb_chars.length #=> 12 # - # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware so we don't need - # a proxy class any more. This means that +mb_chars+ makes it easier to write code that runs on multiple Ruby - # versions. + # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that + # it becomes easy to run one version of your code on multiple Ruby versions. # - # == Method chaining + # == Method chaining # # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows # method chaining on the result of any of these methods. @@ -32,12 +33,12 @@ module ActiveSupport #:nodoc: # # == Interoperability and configuration # - # The Char object tries to be as interchangeable with String objects as possible: sorting and comparing between + # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between # String and Char work like expected. The bang! methods change the internal string representation in the Chars # object. Interoperability problems can be resolved easily with a +to_s+ call. # # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For - # information about how to change the default Multibyte behaviour, see ActiveSupport::Multibyte. + # information about how to change the default Multibyte behaviour see ActiveSupport::Multibyte. def mb_chars if ActiveSupport::Multibyte.proxy_class.wants?(self) ActiveSupport::Multibyte.proxy_class.new(self) @@ -56,15 +57,11 @@ module ActiveSupport #:nodoc: alias chars mb_chars end else - # In Ruby 1.9 and newer +mb_chars+ returns self. In Ruby 1.8 and older +mb_chars+ creates and returns an - # Unicode safe proxy for string operations, this makes it easier to write code that runs on multiple Ruby - # versions. - def mb_chars + def mb_chars #:nodoc self end - # Returns true if the string has valid UTF-8 encoding. - def is_utf8? + def is_utf8? #:nodoc case encoding when Encoding::UTF_8 valid_encoding? diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb index 63c0d50..018aafe 100644 --- a/activesupport/lib/active_support/multibyte.rb +++ b/activesupport/lib/active_support/multibyte.rb @@ -5,7 +5,7 @@ require 'active_support/multibyte/exceptions' require 'active_support/multibyte/unicode_database' module ActiveSupport #:nodoc: - module Multibyte #:nodoc: + module Multibyte # A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more # information about normalization. NORMALIZATIONS_FORMS = [:c, :kc, :d, :kd] @@ -30,4 +30,4 @@ module ActiveSupport #:nodoc: mattr_accessor :proxy_class self.proxy_class = ActiveSupport::Multibyte::Chars end -end \ No newline at end of file +end diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index 27cc3c6..c613679 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -2,7 +2,7 @@ module ActiveSupport #:nodoc: module Multibyte #:nodoc: - # Chars enables you to work transparently with multibyte encodings in the Ruby String class without having extensive + # Chars enables you to work transparently with UTF-8 encoding in the Ruby String class without having extensive # knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an # encoding safe manner. All the normal String methods are also implemented on the proxy. # @@ -88,14 +88,14 @@ module ActiveSupport #:nodoc: alias to_s wrapped_string alias to_str wrapped_string - # Creates a new Chars instance. +string+ is the wrapped string. if '1.9'.respond_to?(:force_encoding) + # Creates a new Chars instance by wrapping _string_. def initialize(string) @wrapped_string = string @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? end else - def initialize(string) + def initialize(string) #:nodoc: @wrapped_string = string end end @@ -121,10 +121,10 @@ module ActiveSupport #:nodoc: true end - # Returns +true+ if the Chars class can and should act as a proxy for the string +string+. Returns + # Returns +true+ if the Chars class can and should act as a proxy for the string _string_. Returns # +false+ otherwise. def self.wants?(string) - RUBY_VERSION < '1.9' && $KCODE == 'UTF8' && consumes?(string) + $KCODE == 'UTF8' && consumes?(string) end # Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise. @@ -138,9 +138,9 @@ module ActiveSupport #:nodoc: include Comparable - # Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the - # object on the right side of the operation. It accepts any object that implements +to_s+. See String.<=> - # for more details. + # Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, + # equal or after the object on the right side of the operation. It accepts any object that implements +to_s+. + # See String#<=> for more details. # # Example: # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1 @@ -148,7 +148,7 @@ module ActiveSupport #:nodoc: @wrapped_string <=> other.to_s end - # Returns a new Chars object containing the other object concatenated to the string. + # Returns a new Chars object containing the _other_ object concatenated to the string. # # Example: # ('Café'.mb_chars + ' périferôl').to_s #=> "Café périferôl" @@ -156,7 +156,7 @@ module ActiveSupport #:nodoc: self << other end - # Like String.=~ only it returns the character offset (in codepoints) instead of the byte offset. + # Like String#=~ only it returns the character offset (in codepoints) instead of the byte offset. # # Example: # 'Café périferôl'.mb_chars =~ /ô/ #=> 12 @@ -164,7 +164,7 @@ module ActiveSupport #:nodoc: translate_offset(@wrapped_string =~ other) end - # Works just like String#split, with the exception that the items in the resulting list are Chars + # Works just like String#split, with the exception that the items in the resulting list are Chars # instances instead of String. This makes chaining methods easier. # # Example: @@ -173,7 +173,7 @@ module ActiveSupport #:nodoc: @wrapped_string.split(*args).map { |i| i.mb_chars } end - # Inserts the passed string at specified codepoint offsets + # Inserts the passed string at specified codepoint offsets. # # Example: # 'Café'.mb_chars.insert(4, ' périferôl').to_s #=> "Café périferôl" @@ -189,7 +189,7 @@ module ActiveSupport #:nodoc: self end - # Returns true if contained string contains +other+. Returns false otherwise. + # Returns +true+ if contained string contains _other_. Returns +false+ otherwise. # # Example: # 'Café'.mb_chars.include?('é') #=> true @@ -198,17 +198,17 @@ module ActiveSupport #:nodoc: @wrapped_string.include?(other) end - # Returns the position of the passed argument in the string, counting in codepoints + # Returns the position _needle_ in the string, counting in codepoints. Returns +nil+ if _needle_ isn't found. # # Example: # 'Café périferôl'.mb_chars.index('ô') #=> 12 - def index(*args) - index = @wrapped_string.index(*args) + # 'Café périferôl'.mb_chars.index(/\w/u) #=> 0 + def index(needle, offset=0) + index = @wrapped_string.index(needle, offset) index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil end - # Works just like the indexed replace method on string, except instead of byte offsets you specify - # character offsets. + # Like String#[]=, except instead of byte offsets you specify character offsets. # # Example: # @@ -248,7 +248,7 @@ module ActiveSupport #:nodoc: end end - # Works just like String#rjust, only integer specifies characters instead of bytes. + # Works just like String#rjust, only integer specifies characters instead of bytes. # # Example: # @@ -261,7 +261,7 @@ module ActiveSupport #:nodoc: justify(integer, :right, padstr) end - # Works just like String#ljust, only integer specifies characters instead of bytes. + # Works just like String#ljust, only integer specifies characters instead of bytes. # # Example: # @@ -274,7 +274,7 @@ module ActiveSupport #:nodoc: justify(integer, :left, padstr) end - # Works just like String#center, only integer specifies characters instead of bytes. + # Works just like String#center, only integer specifies characters instead of bytes. # # Example: # @@ -308,7 +308,7 @@ module ActiveSupport #:nodoc: end alias_method :length, :size - # Reverses all characters in the string + # Reverses all characters in the string. # # Example: # 'Café'.mb_chars.reverse.to_s #=> 'éfaC' @@ -343,7 +343,7 @@ module ActiveSupport #:nodoc: end alias_method :[], :slice - # Convert characters in the string to uppercase + # Convert characters in the string to uppercase. # # Example: # 'Laurent, òu sont les tests?'.mb_chars.upcase.to_s #=> "LAURENT, ÒU SONT LES TESTS?" @@ -351,7 +351,7 @@ module ActiveSupport #:nodoc: apply_mapping :uppercase_mapping end - # Convert characters in the string to lowercase + # Convert characters in the string to lowercase. # # Example: # 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s #=> "věda a výzkum" @@ -359,7 +359,7 @@ module ActiveSupport #:nodoc: apply_mapping :lowercase_mapping end - # Converts the first character to uppercase and the remainder to lowercase + # Converts the first character to uppercase and the remainder to lowercase. # # Example: # 'über'.mb_chars.capitalize.to_s #=> "Über" @@ -418,6 +418,7 @@ module ActiveSupport #:nodoc: self.class.g_unpack(@wrapped_string).length end + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string. def tidy_bytes chars(self.class.tidy_bytes(@wrapped_string)) end @@ -435,24 +436,35 @@ module ActiveSupport #:nodoc: class << self - # Unpack the string at codepoints boundaries - def u_unpack(str) + # Unpack the string at codepoints boundaries. Raises an EncodingError when the encoding of the string isn't + # valid UTF-8. + # + # Example: + # Chars.u_unpack('Café') #=> [67, 97, 102, 233] + def u_unpack(string) begin - str.unpack 'U*' + string.unpack 'U*' rescue ArgumentError raise EncodingError.new('malformed UTF-8 character') end end - # Detect whether the codepoint is in a certain character class. Primarily used by the - # grapheme cluster support. + # Detect whether the codepoint is in a certain character class. Returns +true+ when it's in the specified + # character class and +false+ otherwise. Valid character classes are: :cr, :lf, :l, + # :v, :lv, :lvt and :t. + # + # Primarily used by the grapheme cluster support. def in_char_class?(codepoint, classes) classes.detect { |c| UCD.boundary[c] === codepoint } ? true : false end - # Unpack the string at grapheme boundaries - def g_unpack(str) - codepoints = u_unpack(str) + # Unpack the string at grapheme boundaries. Returns a list of character lists. + # + # Example: + # Chars.g_unpack('क्षि') #=> [[2325, 2381], [2359], [2367]] + # Chars.g_unpack('Café') #=> [[67], [97], [102], [233]] + def g_unpack(string) + codepoints = u_unpack(string) unpacked = [] pos = 0 marker = 0 @@ -481,13 +493,15 @@ module ActiveSupport #:nodoc: unpacked end - # Reverse operation of g_unpack + # Reverse operation of g_unpack. + # + # Example: + # Chars.g_pack(Chars.g_unpack('क्षि')) #=> 'क्षि' def g_pack(unpacked) (unpacked.flatten).pack('U*') end - # Generates a padding string of a certain size. - def padding(padsize, padstr=' ') + def padding(padsize, padstr=' ') #:nodoc: if padsize != 0 new(padstr * ((padsize / u_unpack(padstr).size) + 1)).slice(0, padsize) else @@ -495,7 +509,7 @@ module ActiveSupport #:nodoc: end end - # Re-order codepoints so the string becomes canonical + # Re-order codepoints so the string becomes canonical. def reorder_characters(codepoints) length = codepoints.length- 1 pos = 0 @@ -511,7 +525,7 @@ module ActiveSupport #:nodoc: codepoints end - # Decompose composed characters to the decomposed form + # Decompose composed characters to the decomposed form. def decompose_codepoints(type, codepoints) codepoints.inject([]) do |decomposed, cp| # if it's a hangul syllable starter character @@ -532,7 +546,7 @@ module ActiveSupport #:nodoc: end end - # Compose decomposed characters to the composed form + # Compose decomposed characters to the composed form. def compose_codepoints(codepoints) pos = 0 eoa = codepoints.length - 1 @@ -591,9 +605,9 @@ module ActiveSupport #:nodoc: codepoints end - # Replaces all the non-UTF-8 bytes by their iso-8859-1 or cp1252 equivalent resulting in a valid UTF-8 string - def tidy_bytes(str) - str.split(//u).map do |c| + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string. + def tidy_bytes(string) + string.split(//u).map do |c| if !UTF8_PAT.match(c) n = c.unpack('C')[0] n < 128 ? n.chr : @@ -608,8 +622,7 @@ module ActiveSupport #:nodoc: protected - # Translate a byte offset in the wrapped string to a character offset by looking for the character boundary - def translate_offset(byte_offset) + def translate_offset(byte_offset) #:nodoc: return nil if byte_offset.nil? return 0 if @wrapped_string == '' chunk = @wrapped_string[0..byte_offset] @@ -629,9 +642,7 @@ module ActiveSupport #:nodoc: end end - # Justifies a string in a certain way. Valid values for way are :right, :left and - # :center. - def justify(integer, way, padstr=' ') + def justify(integer, way, padstr=' ') #:nodoc: raise ArgumentError, "zero width padding" if padstr.length == 0 padsize = integer - size padsize = padsize > 0 ? padsize : 0 @@ -648,8 +659,7 @@ module ActiveSupport #:nodoc: chars(result) end - # Map codepoints to one of it's attributes. - def apply_mapping(mapping) + def apply_mapping(mapping) #:nodoc: chars(self.class.u_unpack(@wrapped_string).map do |codepoint| cp = UCD.codepoints[codepoint] if cp and (ncp = cp.send(mapping)) and ncp > 0 @@ -660,9 +670,8 @@ module ActiveSupport #:nodoc: end.pack('U*')) end - # Creates a new instance - def chars(str) - self.class.new(str) + def chars(string) #:nodoc: + self.class.new(string) end end end diff --git a/activesupport/lib/active_support/multibyte/exceptions.rb b/activesupport/lib/active_support/multibyte/exceptions.rb index af760cc..62066e3 100644 --- a/activesupport/lib/active_support/multibyte/exceptions.rb +++ b/activesupport/lib/active_support/multibyte/exceptions.rb @@ -2,6 +2,7 @@ module ActiveSupport #:nodoc: module Multibyte #:nodoc: + # Raised when a problem with the encoding was found. class EncodingError < StandardError; end end end \ No newline at end of file -- 1.6.0 From 30769ed010d1e44bde1fe50707e7d6eb7772afc7 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Fri, 13 Jun 2008 15:34:51 +0200 Subject: [PATCH] Remove special 1.9 version of excerpt helper. --- actionpack/lib/action_view/helpers/text_helper.rb | 90 ++++++++++---------- 1 files changed, 45 insertions(+), 45 deletions(-) diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 4e37114..3af7440 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -121,57 +121,57 @@ module ActionView end end - # Extracts an excerpt from +text+ that matches the first instance of +phrase+. - # The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters - # defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+, - # then the :omission option (which defaults to "...") will be prepended/appended accordingly. The resulting string - # will be stripped in any case. If the +phrase+ isn't found, nil is returned. - # - # ==== Examples - # excerpt('This is an example', 'an', :radius => 5) - # # => ...s is an exam... - # - # excerpt('This is an example', 'is', :radius => 5) - # # => This is a... - # - # excerpt('This is an example', 'is') - # # => This is an example - # - # excerpt('This next thing is an example', 'ex', :radius => 2) - # # => ...next... - # - # excerpt('This is also an example', 'an', :radius => 8, :omission => ' ') - # # => is also an example - # - # You can still use excerpt with the old API that accepts the - # +radius+ as its optional third and the +ellipsis+ as its - # optional forth parameter: - # excerpt('This is an example', 'an', 5) # => ...s is an exam... - # excerpt('This is also an example', 'an', 8, ' ') # => is also an example - def excerpt(text, phrase, *args) - options = args.extract_options! - unless args.empty? - options[:radius] = args[0] || 100 - options[:omission] = args[1] || "..." - end - options.reverse_merge!(:radius => 100, :omission => "...") + # Extracts an excerpt from +text+ that matches the first instance of +phrase+. + # The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters + # defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+, + # then the :omission option (which defaults to "...") will be prepended/appended accordingly. The resulting string + # will be stripped in any case. If the +phrase+ isn't found, nil is returned. + # + # ==== Examples + # excerpt('This is an example', 'an', :radius => 5) + # # => ...s is an exam... + # + # excerpt('This is an example', 'is', :radius => 5) + # # => This is a... + # + # excerpt('This is an example', 'is') + # # => This is an example + # + # excerpt('This next thing is an example', 'ex', :radius => 2) + # # => ...next... + # + # excerpt('This is also an example', 'an', :radius => 8, :omission => ' ') + # # => is also an example + # + # You can still use excerpt with the old API that accepts the + # +radius+ as its optional third and the +ellipsis+ as its + # optional forth parameter: + # excerpt('This is an example', 'an', 5) # => ...s is an exam... + # excerpt('This is also an example', 'an', 8, ' ') # => is also an example + def excerpt(text, phrase, *args) + options = args.extract_options! + unless args.empty? + options[:radius] = args[0] || 100 + options[:omission] = args[1] || "..." + end + options.reverse_merge!(:radius => 100, :omission => "...") - if text && phrase - phrase = Regexp.escape(phrase) + if text && phrase + phrase = Regexp.escape(phrase) - if found_pos = text.mb_chars =~ /(#{phrase})/i - start_pos = [ found_pos - options[:radius], 0 ].max - end_pos = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min + if found_pos = text.mb_chars =~ /(#{phrase})/i + start_pos = [ found_pos - options[:radius], 0 ].max + end_pos = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min - prefix = start_pos > 0 ? options[:omission] : "" - postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : "" + prefix = start_pos > 0 ? options[:omission] : "" + postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : "" - prefix + text.mb_chars[start_pos..end_pos].strip + postfix - else - nil - end + prefix + text.mb_chars[start_pos..end_pos].strip + postfix + else + nil end end + end # Attempts to pluralize the +singular+ word unless +count+ is 1. If # +plural+ is supplied, it will use that when count is > 1, otherwise -- 1.6.0 From d197ef76360f34ec032ce09a89ca4bc27be3b242 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Sat, 21 Jun 2008 13:27:04 +0200 Subject: [PATCH] Non-string results from forwarded methods should be returned vertabim. When Chars forwards a method for the wrapped string and the result is an integer, for instance, it should be returned vertabim and not wrapped in a new chars proxy. --- .../lib/active_support/multibyte/chars.rb | 5 +++-- activesupport/test/multibyte_chars_test.rb | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index c613679..b3fdcdc 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -106,10 +106,11 @@ module ActiveSupport #:nodoc: @wrapped_string.__send__(method, *args, &block) self else - chars(@wrapped_string.__send__(method, *args, &block)) + result = @wrapped_string.__send__(method, *args, &block) + result.kind_of?(String) ? chars(result) : result end end - + # Returns +true+ if _obj_ responds to the given method. Private methods are included in the search # only if the optional second parameter evaluates to +true+. def respond_to?(method, include_private=false) diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 6400707..2fde4d3 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -21,8 +21,9 @@ module MultibyteTest end class String - def __string_for_multibyte_testing; self; end - def __string_for_multibyte_testing!; self; end + def __method_for_multibyte_testing_with_integer_result; 1; end + def __method_for_multibyte_testing; 'result'; end + def __method_for_multibyte_testing!; 'result'; end end class MultibyteCharsTest < Test::Unit::TestCase @@ -40,7 +41,7 @@ class MultibyteCharsTest < Test::Unit::TestCase def test_should_allow_method_calls_to_string assert_nothing_raised do - @chars.__string_for_multibyte_testing + @chars.__method_for_multibyte_testing end assert_raises NoMethodError do @chars.__unknown_method @@ -48,19 +49,23 @@ class MultibyteCharsTest < Test::Unit::TestCase end def test_forwarded_method_calls_should_return_new_chars_instance - assert @chars.__string_for_multibyte_testing.kind_of?(@proxy_class) - assert_not_equal @chars.object_id, @chars.__string_for_multibyte_testing.object_id + assert @chars.__method_for_multibyte_testing.kind_of?(@proxy_class) + assert_not_equal @chars.object_id, @chars.__method_for_multibyte_testing.object_id end def test_forwarded_bang_method_calls_should_return_the_original_chars_instance - assert @chars.__string_for_multibyte_testing!.kind_of?(@proxy_class) - assert_equal @chars.object_id, @chars.__string_for_multibyte_testing!.object_id + assert @chars.__method_for_multibyte_testing!.kind_of?(@proxy_class) + assert_equal @chars.object_id, @chars.__method_for_multibyte_testing!.object_id end def test_methods_are_forwarded_to_wrapped_string_for_byte_strings assert_equal BYTE_STRING.class, BYTE_STRING.mb_chars.class end + def test_forwarded_method_with_non_string_result_should_be_returned_vertabim + assert_equal ''.__method_for_multibyte_testing_with_integer_result, @chars.__method_for_multibyte_testing_with_integer_result + end + def test_should_concatenate assert_equal 'ab', 'a'.mb_chars + 'b' assert_equal 'ab', 'a' + 'b'.mb_chars -- 1.6.0 From 0f21fd468651f60272a6e8c345401eca5ba3f5eb Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Sat, 21 Jun 2008 13:49:39 +0200 Subject: [PATCH] Whitespace fixes. --- .../active_support/core_ext/string/multibyte.rb | 4 ++-- .../lib/active_support/multibyte/chars.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb index 3bf79bc..6d25286 100644 --- a/activesupport/lib/active_support/core_ext/string/multibyte.rb +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -46,7 +46,7 @@ module ActiveSupport #:nodoc: self end end - + # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have # them), returns false otherwise. def is_utf8? @@ -60,7 +60,7 @@ module ActiveSupport #:nodoc: def mb_chars #:nodoc self end - + def is_utf8? #:nodoc case encoding when Encoding::UTF_8 diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index b3fdcdc..bea4732 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -292,23 +292,23 @@ module ActiveSupport #:nodoc: def rstrip chars(@wrapped_string.gsub(UNICODE_TRAILERS_PAT, '')) end - + # Strips entire range of Unicode whitespace from the left of the string. def lstrip chars(@wrapped_string.gsub(UNICODE_LEADERS_PAT, '')) end - + # Strips entire range of Unicode whitespace from the right and left of the string. def strip rstrip.lstrip end - + # Returns the number of codepoints in the string def size self.class.u_unpack(@wrapped_string).size end alias_method :length, :size - + # Reverses all characters in the string. # # Example: @@ -316,7 +316,7 @@ module ActiveSupport #:nodoc: def reverse chars(self.class.u_unpack(@wrapped_string).reverse.pack('U*')) end - + # Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that # character. # -- 1.6.0 From 33599d7a08bdb2ab7211a5e089089e72193c580f Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Fri, 15 Aug 2008 21:22:47 +0200 Subject: [PATCH] Fix a test that assumes .mb_chars to always return an instance of the proxy_class. --- activerecord/test/cases/base_test.rb | 30 +++++++++++++++++++++++------- 1 files changed, 23 insertions(+), 7 deletions(-) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index fb9e743..4c62898 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1420,15 +1420,17 @@ class BasicsTest < ActiveRecord::TestCase if RUBY_VERSION < '1.9' def test_quote_chars - str = 'The Narrator' - topic = Topic.create(:author_name => str) - assert_equal str, topic.author_name + with_kcode('UTF8') do + str = 'The Narrator' + topic = Topic.create(:author_name => str) + assert_equal str, topic.author_name - assert_kind_of ActiveSupport::Multibyte.proxy_class, str.mb_chars - topic = Topic.find_by_author_name(str.mb_chars) + assert_kind_of ActiveSupport::Multibyte.proxy_class, str.mb_chars + topic = Topic.find_by_author_name(str.mb_chars) - assert_kind_of Topic, topic - assert_equal str, topic.author_name, "The right topic should have been found by name even with name passed as Chars" + assert_kind_of Topic, topic + assert_equal str, topic.author_name, "The right topic should have been found by name even with name passed as Chars" + end end end @@ -2021,4 +2023,18 @@ class BasicsTest < ActiveRecord::TestCase ensure ActiveRecord::Base.logger = original_logger end + + private + def with_kcode(kcode) + if RUBY_VERSION < '1.9' + orig_kcode, $KCODE = $KCODE, kcode + begin + yield + ensure + $KCODE = orig_kcode + end + else + yield + end + end end -- 1.6.0 From a323d7a65d8280b3795a605c73e223416bf4c9c6 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Sun, 31 Aug 2008 13:35:19 +0200 Subject: [PATCH] Add tests for u_unpack to make sure it raises an EncodingError on invalid UTF-8 strings. --- .../lib/active_support/multibyte/chars.rb | 2 +- activesupport/test/multibyte_chars_test.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index bea4732..eca92f2 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -446,7 +446,7 @@ module ActiveSupport #:nodoc: begin string.unpack 'U*' rescue ArgumentError - raise EncodingError.new('malformed UTF-8 character') + raise EncodingError, 'malformed UTF-8 character' end end diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 2fde4d3..8aae66b 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -82,6 +82,17 @@ class MultibyteCharsTest < Test::Unit::TestCase assert !@proxy_class.consumes?(BYTE_STRING) end + def test_unpack_utf8_strings + assert_equal 4, @proxy_class.u_unpack(UNICODE_STRING).length + assert_equal 5, @proxy_class.u_unpack(ASCII_STRING).length + end + + def test_unpack_raises_encoding_error_on_broken_strings + assert_raises(ActiveSupport::Multibyte::EncodingError) do + @proxy_class.u_unpack(BYTE_STRING) + end + end + if RUBY_VERSION < '1.9' def test_concatenation_should_return_a_proxy_class_instance assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars + 'b').class -- 1.6.0 From c2c18016c28ff0cd71795d0e03bdd18c57236a48 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Wed, 11 Jun 2008 18:03:03 +0200 Subject: [PATCH] Simplify ActiveSupport::Multibyte and make it run on Ruby 1.9. * Unicode methods are now defined directly on Chars instead of a handler * Updated Unicode database to Unicode 5.1.0 * Improved documentation --- activesupport/lib/active_support/multibyte.rb | 2 +- .../lib/active_support/multibyte/exceptions.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb index 018aafe..23be2cd 100644 --- a/activesupport/lib/active_support/multibyte.rb +++ b/activesupport/lib/active_support/multibyte.rb @@ -30,4 +30,4 @@ module ActiveSupport #:nodoc: mattr_accessor :proxy_class self.proxy_class = ActiveSupport::Multibyte::Chars end -end +end \ No newline at end of file diff --git a/activesupport/lib/active_support/multibyte/exceptions.rb b/activesupport/lib/active_support/multibyte/exceptions.rb index 62066e3..72007f9 100644 --- a/activesupport/lib/active_support/multibyte/exceptions.rb +++ b/activesupport/lib/active_support/multibyte/exceptions.rb @@ -5,4 +5,4 @@ module ActiveSupport #:nodoc: # Raised when a problem with the encoding was found. class EncodingError < StandardError; end end -end \ No newline at end of file +end -- 1.6.0 From 42cc0d8460b52cfc6ab3d9dd068d52687fee0b23 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Fri, 13 Jun 2008 14:27:07 +0200 Subject: [PATCH] Improve documentation. --- activesupport/lib/active_support/multibyte.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb index 23be2cd..018aafe 100644 --- a/activesupport/lib/active_support/multibyte.rb +++ b/activesupport/lib/active_support/multibyte.rb @@ -30,4 +30,4 @@ module ActiveSupport #:nodoc: mattr_accessor :proxy_class self.proxy_class = ActiveSupport::Multibyte::Chars end -end \ No newline at end of file +end -- 1.6.0 From af1099dedc4d40f22a8406d191083057a9e19afd Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Fri, 12 Sep 2008 00:29:55 +0200 Subject: [PATCH] Move MultibyteTestHelper module to a separate file. - Move the MultibyteTestHelper module to a separate file so it can me used by multiple tests. - Make the conformance tests run again by including the MultibyteTestHelper. --- activesupport/test/multibyte_chars_test.rb | 25 ++++--------------------- activesupport/test/multibyte_conformance.rb | 4 +++- activesupport/test/multibyte_test_helper.rb | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 activesupport/test/multibyte_test_helper.rb diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 8aae66b..c3f1279 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -1,24 +1,7 @@ # encoding: utf-8 require 'abstract_unit' - -module MultibyteTest - UNICODE_STRING = 'こにちわ' - ASCII_STRING = 'ohayo' - BYTE_STRING = "\270\236\010\210\245" - - def chars(str) - ActiveSupport::Multibyte::Chars.new(str) - end - - def inspect_codepoints(str) - str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ') - end - - def assert_equal_codepoints(expected, actual, message=nil) - assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message) - end -end +require 'multibyte_test_helper' class String def __method_for_multibyte_testing_with_integer_result; 1; end @@ -27,7 +10,7 @@ class String end class MultibyteCharsTest < Test::Unit::TestCase - include MultibyteTest + include MultibyteTestHelper def setup @proxy_class = ActiveSupport::Multibyte::Chars @@ -113,7 +96,7 @@ class MultibyteCharsTest < Test::Unit::TestCase end class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase - include MultibyteTest + include MultibyteTestHelper def setup @chars = UNICODE_STRING.dup.mb_chars @@ -445,7 +428,7 @@ end # for the implementation of these features should run on all Ruby versions and shouldn't be tested # through the proxy methods. class MultibyteCharsExtrasTest < Test::Unit::TestCase - include MultibyteTest + include MultibyteTestHelper if RUBY_VERSION >= '1.9' def test_tidy_bytes_is_broken_on_1_9_0 diff --git a/activesupport/test/multibyte_conformance.rb b/activesupport/test/multibyte_conformance.rb index 87e2cd0..257bd7d 100644 --- a/activesupport/test/multibyte_conformance.rb +++ b/activesupport/test/multibyte_conformance.rb @@ -1,4 +1,6 @@ require 'abstract_unit' +require 'multibyte_test_helper' + require 'fileutils' require 'open-uri' require 'tmpdir' @@ -22,7 +24,7 @@ class Downloader end class MultibyteConformanceTest < Test::Unit::TestCase - include MultibyteTest + include MultibyteTestHelper UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::UNICODE_VERSION}/ucd" UNIDATA_FILE = '/NormalizationTest.txt' diff --git a/activesupport/test/multibyte_test_helper.rb b/activesupport/test/multibyte_test_helper.rb new file mode 100644 index 0000000..077b57c --- /dev/null +++ b/activesupport/test/multibyte_test_helper.rb @@ -0,0 +1,17 @@ +module MultibyteTestHelper + UNICODE_STRING = 'こにちわ' + ASCII_STRING = 'ohayo' + BYTE_STRING = "\270\236\010\210\245" + + def chars(str) + ActiveSupport::Multibyte::Chars.new(str) + end + + def inspect_codepoints(str) + str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ') + end + + def assert_equal_codepoints(expected, actual, message=nil) + assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message) + end +end \ No newline at end of file -- 1.6.0